题目链接:
解题思路:
题目大意:
有n (n<16345)个人,每个人有三个数(小于1000且最多两位小数点),表示答对对应题的得分。规定总分越高的人rank越高。总分相同,id小的rank高。现在知道rank,问
这个rank是否可能,如果可能,就输出rank最小的那个人的最大得分是多少,反之,则输出No solution。
算法思想:
3个数,最多8种情况。然后按照rank依次向下推,每次选择一个最大的能符合条件的分数,当作这个人的分数。如果能推下去,则ok,否则,不能。
注意:
精度很坑。需要先转换成整数才过了。。。
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
struct node{
int a[3],num[8];
}no[17000];
int Rank[17000];
int main(){
int n,t = 1;
while(scanf("%d",&n),n){
for(int i = 1; i <= n; i++){
double x;
for(int j = 0; j < 3; j++){
scanf("%lf",&x);
no[i].a[j] = (int)((x+1e-4)*100);//x+1e-4这步必须要加,不然会因为精度问题出错
}
for(int j = 0; j < 8; j++){
int sum = 0;
for(int k = 0; k < 3; k++){
if((j >> k) & 1)
sum += no[i].a[k];
}
no[i].num[j] = sum;
}
sort(no[i].num,no[i].num+8);
}
int tmpnum,tmpsum = INF;
int flag;
for(int i = 1; i <= n; i++)
scanf("%d",&Rank[i]);
for(int i = 1; i <= n; i++){
flag = 0;
for(int j = 7; j >= 0; j--){
if(no[Rank[i]].num[j] < tmpsum || (no[Rank[i]].num[j] == tmpsum && Rank[i] > tmpnum)){
flag = 1;
tmpnum = Rank[i];
tmpsum = no[Rank[i]].num[j];
}
if(flag)
break;
}
if(!flag)
break;
}
if(!flag)
printf("Case %d: No solution\n",t++);
else
printf("Case %d: %.2lf\n",t++,tmpsum/100.0);
}
return 0;
}