题目大意:题目比较长,耐心读完发现题意蛮简单。就是某学校要从n个acmer中选m个人去比赛,因为名额有限,所以要给每个acmer评分,取前m个去比赛。一共有4条评分准则:
1:该校有一个oj,oj上有2类题目,题号均为4位无重复的数字,对于每个acmer,在oj上过了第一类题目的每道题目加2.5分,第二类题目每道加1.5分,其他的如果题号是质数,每道加1分,如果不符合以上3个条件任意一个,每道加0.3分。
2:该校举行的校赛中(组队赛),取得优异成绩队伍的成员可以加法,具体的加法是:
如果该acmer所在队伍在校赛中得1等奖,该acmer加36分;2等奖成员加27分;3等奖成员加18分;其他奖没有分。
3:如果某acmer做过某种比赛,每次做完后会有一个rating,取历次比赛rating的第3大的rating,带入公式p = max(0,(rating - 1200)/100) * 1.5,则总分加上p;
4:如果该acmer是个妹子,加33分!!
综上,算出每个acmer的总分,取前m为即可。
题目分析:纯模拟,还分析什么啊, 直接搞!详情请见代码:
#include <iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int N = 501;
const double eps = 1e-4;
int maomao[N],old[N];
bool is[10000];
int n,m,r,s,teamnum;
struct node1
{
char t_name[31];
int prize;
}team[N];
struct node2
{
char name[31],team[31],sex[31];
double score;
int p,c;
int solved[1001],rank[1001];
}app[N];
void getprm()
{
int i,j;
memset(is,0,sizeof(is));
for(i = 4;i <= 10000;i += 2)
is[i] = 1;
for(i = 3;i <= 10000;i += 2)
{
if(is[i] == 0)
{
for(j = i + i;j <= 10000;j += i)
is[j] = 1;
}
}
}
int ismaomao(int x)
{
int i;
for(i = 0;i < r;i ++)
if(maomao[i] == x)
return 1;
return 0;
}
int isold(int x)
{
int i;
for(i = 0;i < s;i ++)
if(old[i] == x)
return 1;
return 0;
}
int isprime(int x)
{
int i;
for(i = 2;i * i <= x;i ++)
if(x % i == 0)
return 0;
return 1;
}
int cmp(struct node2 a,struct node2 b)
{
if(fabs(a.score - b.score) < eps)
return strcmp(a.name,b.name) < 0;
else
return a.score > b.score;
}
int teamprize(int id)
{
int i;
for(i = 0;i < teamnum;i ++)
{
if(strcmp(app[id].team,team[i].t_name) == 0)
return team[i].prize;
}
return 0;
}
int main()
{
getprm();
int t;
int i,j;
//while(scanf("%d",&t) != EOF)
//{
// printf("%d\n",isprime(t));
//}
scanf("%d",&t);
while(t --)
{
scanf("%d%d",&n,&m);
scanf("%d",&r);
for(i = 0;i < r;i ++)
scanf("%d",&maomao[i]);
sort(maomao,maomao + r);
scanf("%d",&s);
for(i = 0;i < s;i ++)
scanf("%d",&old[i]);
sort(old,old + s);
scanf("%d",&teamnum);
for(i = 0;i < teamnum;i ++)
{
scanf("%s%d",team[i].t_name,&team[i].prize);
}
for(i = 0;i < n;i ++)
{
scanf("%s%s%s%d%d",app[i].name,app[i].team,app[i].sex,&app[i].p,&app[i].c);
if(app[i].sex[0] == 'F')
app[i].score = 33;
else
app[i].score = 0;
for(j = 0;j < app[i].p;j ++)
{
scanf("%d",&app[i].solved[j]);
//if(is[app[i].solved[j]] == 0)
// app[i].score = app[i].score + 1;
if(ismaomao(app[i].solved[j]))
app[i].score = app[i].score + 2.5;
else
{
if(isold(app[i].solved[j]))
app[i].score = app[i].score + 1.5;
else
{
if(isprime(app[i].solved[j]))
app[i].score = app[i].score + 1;
else
app[i].score = app[i].score + 0.3;
}
}
}
for(j = 0;j < app[i].c;j ++)
scanf("%d",&app[i].rank[j]);
switch(teamprize(i))
{
case 1:app[i].score = app[i].score + 36;
break;
case 2:app[i].score = app[i].score + 27;
break;
case 3:app[i].score = app[i].score + 18;
break;
default:break;
}
sort(app[i].rank,app[i].rank + app[i].c);
if(app[i].c >= 3)
{
int tmp = app[i].rank[app[i].c - 3];
double tp = (tmp - 1200) / 100.0;
tp = tp * 1.5;
if(tp > 0)
app[i].score = app[i].score + tp;
}
}
sort(app,app + n,cmp);
for(i = 0;i < m;i ++)
printf("%s %.3lf\n",app[i].name,app[i].score);
}
return 0;
}
这道题目比较不难,但是很晚才有人过。可能这次比赛简单题目太多了,所以都忙着水水题去了,呵呵。比赛中有点小匆忙,小手一抖,写错了一个变量,WA了6次才过,这都是教训啊啊啊。