nBOJ3 - Guess(也就是oBOJ的1002)
Accept:180 | Submit:335 |
Time Limit:3000MS | Memory Limit:65536KB |
Description
A
competition was just over. It had 3 problems and n players. Each player
had an ID number from 1 to n. The final rank was decided by the total
score of the 3 problems. The higher the total score was, the higher a
player ranked (the smaller the rank number). If two players got the same
total score, the one with the smaller ID number got a higher rank.
We’ve known for each problem, how much score each player might get if he
din’t solve totally wrong (if solved totally wrong, the player got zero
in the problem). However, we don’t know whether a player did get score
in a problem. For a predicted final rank, you need to judge if the rank
is possible.
Input
Input
contains several cases. For each case, the first line is an integer n,
(n <= 16384) to indicate the number of players, followed by n lines,
the ith of which contains three real numbers a, b, c (0<=a, b, c <
1000. a, b and c have 2 decimal places at most.) to respectively
indicate the score of each problem Player i might get if he didn’t solve
totally wrong. Another line containing n integers follows to indicate
the player ID number in the order from rank 1st to rank nth .
The last case is followed by a line containing only a zero.
Output
For
each case, if the rank is possible, output the highest possible total
score for the player with the lowest rank (calculate to 2 decimal
places), otherwise output “No solution" (quotes for clarity).
Sample Input
3
100 200 300
100 200 300
100 200 300
1 2 3
3
100 200 300
100 200 300
100 200 300
3 2 1
0
Sample Output
Case 1: 600.00
Case 2: 400.00
Source
ACM Beijing 2006-E
贪心的题。代码注释说明了做法。说两个注意事项就好。
一是这题精度卡的很变态。必须转换为int截断再变回double。
二是No Solution前面也要输出case号,这个题干中没有提的很明显。
吐槽:cin和scanf的效率真的差很多。
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int main(void)
{
int n,count(0);
while(scanf("%d",&n) && n)
{
++count;
int *rank = new int[n+5];//rank数组:rank[i]表示第i+1位置的人的序号
int **score = new int*[n];
bool fail = false;
int lastscore(INT_MAX),lastone(INT_MAX),temp;//上一位选手的名次和序号,取一个较大的值用来覆盖
float f1,f2,f3;
for(int i(0);i != n;++i)
{
score[i] = new int[8];
scanf("%f%f%f",&f1,&f2,&f3);
score[i][0] = (int)((f1+0.001)*100);
score[i][1] = (int)((f2+0.001)*100);
score[i][2] = (int)((f3+0.001)*100);
score[i][3] = score[i][0]+score[i][1];
score[i][4] = score[i][1]+score[i][2];
score[i][5] = score[i][0]+score[i][2];
score[i][6] = score[i][0]+score[i][1]+score[i][2];
score[i][7] = 0;
sort(score[i],score[i]+8);//这位选手可能得到的分数,共8种
}
for(int i(0);i != n;++i)
scanf("%d",&rank[i]);
for(int i(0);i != n;++i)
{
int j = rank[i]-1;
int begin = 7;
while(begin >= 0 && (score[j][begin] > lastscore || (score[j][begin] == lastscore
&& j < lastone)))//判断过程,从最大的分数开始:如果不符合要求,则替换为下一个分数,直到begin<0
begin--;
if(begin < 0)//说明不存在满足条件的分数
{
fail = true;
break;
}
else//否则继续测试下一位选手
{
lastone = j;
lastscore = score[j][begin];
}
}
if(!fail)
printf("Case %d: %.2lf\n",count,(double)lastscore/100);
else
printf("Case %d: No solution\n",count);
delete[] rank;
for(int i(0);i != n;++i)
delete[] score[i];
delete[] score;
}
return 0;
}