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 i-th 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 1-st to rank n-th.
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 Explanation:
Case 1:
Rank Player ID Number Problem 1’s Score Problem 2’s Score Problem 3’s Score
1 1 100 200 300
2 2 100 200 300
3 3 100 200 300
Case 2:
Rank Player ID Number Problem 1’s Score Problem 2’s Score Problem 3’s Score
1 3 100 200 300
2 2 0 (wrong) 200 300
3 1 100 0 (wrong) 300
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
就是有n个人,给了3门分数,这个分数真假不定,如果是真的,就是全分,否则就是0分。
现在给了一个序列,表示他们的成绩排列,求最后一名可能的最大分,如果不存在,输出No solution
直接贪心搞啊,第一名满分,然后根据那个判断后面的人在满足条件下得到的最高分,一共就8种情况。
但是,精确2位把我搞成傻逼了……原因应该是计算机存储浮点数的时候并不是精确的等于,会有误差……然后学会了一个神奇的round函数
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
#include<math.h>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
struct Node
{
int a, b, c;
}node[16390];
int ran[16390];
int temp;
bool check(int n, int pre)
{
int ans = -1;
int a[8], t1, t2, t3;
t1 = node[ran[n]].a;
t2 = node[ran[n]].b;
t3 = node[ran[n]].c;
a[0] = t1 + t2 + t3;
a[1] = t1 + t2;
a[2] = t1 + t3;
a[3] = t2 + t3;
a[4] = t1;
a[5] = t2;
a[6] = t3;
a[7] = 0;
if (ran[n] < ran[n - 1])
{
for (int i = 0; i < 8; i++)
{
if (a[i] < pre&&a[i] > ans)
ans = a[i];
}
if (ans != -1)
{
temp = ans;
return true;
}
return false;
}
for (int i = 0; i < 8; i++)
{
if (a[i] <= pre&&a[i] > ans)
ans = a[i];
}
if (ans != -1)
{
temp = ans; return true;
}
return false;
}
int main()
{
#ifdef LOCAL
freopen("C:\\Users\\ΡΡ\\Desktop\\in.txt", "r", stdin);
//freopen("C:\\Users\\ΡΡ\\Desktop\\out.txt","w",stdout);
#endif // LOCAL
int n, kase = 1;
while (scanf("%d", &n) != EOF)
{
if (!n)break;
printf("Case %d: ", kase++);
for (int i = 1; i <= n; i++)
{
double temp1, temp2, temp3;
scanf("%lf%lf%lf", &temp1, &temp2, &temp3);
node[i].a = round(temp1*100.0);
node[i].b = round(temp2*100.0);
node[i].c = round(temp3*100.0);
}
for (int i = 1; i <= n; i++)
scanf("%d", &ran[i]);
int fir = ran[1];
temp = node[fir].a + node[fir].b + node[fir].c;
if (n == 1)
{
double ans = temp*1.0 / 100.0;
printf("%.2lf\n", ans);
}
else if (n >= 2)
{
int i = 2;
while (i <= n&&check(i, temp))
i++;
if (i == n + 1)
{
double ans = temp*1.0 / 100.0;
printf("%.2lf\n", ans);
}
else
printf("No solution\n");
}
}
return 0;
}