VJ question link
Question:
There are n (n <16345) individuals and each person has three numbers (less than 1000 and up to two decimal places), which indicates the score of the corresponding question. The higher the total score, the higher the rank. The total score is the same. The rank with a small ID is high. Now I know rank and ask if this rank is possible. If possible, the person with the smallest rank has a maximum score.
Ideas:
3. A maximum of 8 cases. Then, we will push up from rank, and select a minimum qualified score each time as the score of this person. If you can push it down, OK. Otherwise, no.
Pitfalls:
Precision is very pitfall. It can only be converted to an integer.
Code:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 20000struct Man{ int a[3]; int possible[8]; void read() { for (int i = 0; i < 3; i++) { double tmp; scanf("%lf", &tmp); a[i] = (int)((tmp+1e-4)*100); } for (int i = 0; i < 8; i++) { int sum = 0; for (int j = 0; j < 3; j++) { if ((i>>j)&1) { sum += a[j]; } } possible[i] = sum; } sort(possible, possible+8); }}man[N];int rk[N];int n;bool dfs(int pre, int id) { if (id <= 0) return true; int minres = 0x3f3f3f3f; bool isok = false; for (int i = 7; i >= 0; i--) { if (man[rk[id]].possible[i] > pre || (man[rk[id]].possible[i] == pre && rk[id] < rk[id+1])) { isok = true; minres = min(minres, man[rk[id]].possible[i]); } else break; } if (!isok) return false; return dfs(minres, id-1);}int main() { int cas = 1; while (scanf("%d", &n)!=EOF) { if (n == 0) break; printf("Case %d: ", cas++); for (int i = 1; i <= n; i++) { man[i].read(); } for (int i = 1; i <= n; i++) { scanf("%d",&rk[i]); } int ans = -1; for (int i = 0; i < 8; i++) { if (dfs(man[rk[n]].possible[i], n-1)) { ans = max(ans, man[rk[n]].possible[i]); } else break; } if (ans == -1) { puts("No solution"); } else { printf("%.2f\n", ans/100.0); } } return 0;}
Uvalive 3664: Guess (Greedy Grade E)