题意:给你n个选手的3个预期分数a,b,c . 如果他们其中错一题就只能得0分,否则得预期分,再给你一个序列. 规则:分数低的排后面,分数高的排前面,分数相同的id小的排前面.那么问题是找到符合这个序列的最后一名的最高分数
个人感想:按题意来做,比较简单.
分析:
就是一个贪心,分两种情况.
当前id比前一个大的:-》这样就没有分数相同的限制,直接尝试着从分数减去wa的分数,小于等于前一个就好了.尽可能接近前面一个的分数。
当前id比前一个小的:-》这种情况就要分数必须严格小于前一个的分数了,那么我们再找接近前一个分数的最大值就好了。
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
//#define OUT
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define Clear(x) memset(x,0,sizeof(x))
const int INF=0x3f3f3f3f;
const int maxn=20000;
const double eps=1e-6;
int N;
double Rank[maxn][3];
int S[maxn];
double last;
double goal[8];
double getsum(int id)
{
return Rank[id][0]+Rank[id][1]+Rank[id][2];
}
bool Check(double last,double now,int select)
{
if(select)
{
if(last>now||fabs(last-now)<eps)return true;
}
else
{
if(last>now)return true;
}
return false;
}
void getgoal(int id)
{
goal[0]=0;
goal[1]=Rank[id][0];
goal[2]=Rank[id][1];
goal[3]=Rank[id][2];
goal[4]=Rank[id][0]+Rank[id][1];
goal[5]=Rank[id][0]+Rank[id][2];
goal[6]=Rank[id][1]+Rank[id][2];
goal[7]=Rank[id][0]+Rank[id][1]+Rank[id][2];
sort(goal,goal+8);
}
bool solve()
{
last=getsum(S[1]);
for(int i=2;i<=N;i++)
{
if(S[i]>S[i-1])
{
double now=getsum(S[i]);
getgoal(S[i]);
bool flag=true;
for(int j=0;j<8;j++)
{
if(Check(last,now-goal[j],1))
{
last=now-goal[j];
flag=false;
break;
}
}
if(flag) return false;
}
else
{
double now=getsum(S[i]);
getgoal(S[i]);
bool flag=true;
for(int j=0;j<8;j++)
{
if(Check(last,now-goal[j],0))
{
last=now-goal[j];
flag=false;
break;
}
}
if(flag) return false;
}
}
return true;
}
int main()
{
#ifdef OUT
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
int cas=0;
while(scanf("%d",&N),N)
{
cas++;
for(int i=1;i<=N;i++)
{
for(int j=0;j<3;j++)
{
cin>>Rank[i][j];
}
sort(Rank[i],Rank[i]+3);
}
for(int i=1;i<=N;i++)
{
scanf("%d",&S[i]);
}
if(solve())printf("Case %d: %0.2f\n",cas,last);
else printf("Case %d: No solution\n",cas);
}
return 0;
}