链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4487
题意:
有n(n≤16384)位选手参加编程比赛。比赛有3道题目,每个选手的每道题目都有一个评测之前的预得分
(这个分数和选手提交程序的时间相关,提交得越早,预得分越大)。接下来是系统测试。
如果某道题目未通过测试,则该题的实际得分为0分,否则得分等于预得分。得分相同的选手,ID小的排在前面。
问是否能给出所有3n个得分以及最后的实际名次。如果可能,输出最后一名的最高可能得分。
每个预得分均为小于1000的非负整数,最多保留两位小数。
分析:
贪心一下就好。最重要的是,要精度处理。
代码:
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 6 const int UP = 16384 + 5; 7 int R[UP], S[UP][3]; 8 9 int get(int cur, int a, int b, int c, bool j){ 10 int v[8] = {0, a, b, c, a+b, a+c, b+c, a+b+c}; 11 sort(v, v + 8); 12 for(int i = 7; i >= 0; i--) 13 if(v[i] < cur || (j && v[i] == cur)) return v[i]; 14 return -1; 15 } 16 17 int main(){ 18 int n, cases = 0; 19 while(scanf("%d", &n) && n){ 20 for(int i = 1; i <= n; i++){ 21 for(int t = 0; t < 3; t++){ 22 double x; 23 scanf("%lf", &x); 24 S[i][t] = round(x * 100); //精度处理,先用round函数得出精确的100倍整数值 25 } 26 } 27 for(int i = 1; i <= n; i++) scanf("%d", &R[i]); 28 29 int ans = S[R[1]][0] + S[R[1]][1] + S[R[1]][2]; 30 for(int i = 2; i <= n && ans >= 0; i++) 31 ans = get(ans, S[R[i]][0], S[R[i]][1], S[R[i]][2], R[i-1] < R[i]); 32 if(ans < 0) printf("Case %d: No solution\n", ++cases); 33 else printf("Case %d: %.2f\n", ++cases, ans / 100.0); //最后结果要除以100,变回原样 34 } 35 return 0; 36 }