原题链接
这道题,emmmmmm,贼坑了
测试点4应该是数组大小的问题
这里使用了标记法,108个码标记,提高程序运行的速度
#include<iostream>
#include<string>
#include<cstdlib>
#include<cstring>
#include<cstdio>
using namespace std;
struct node
{
double score;
int anscnt;
int accnt;
int a[109]={0};//标记字母是否在答案里面
char ans[1000];//保存字母答案
};
int main()
{
double socre[1100]={0};//保存成绩
node ans[1100];//保存争取答案
int a[1100][109];//保存错误的信息和次数
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>ans[i].score;
cin>>ans[i].anscnt;
cin>>ans[i].accnt;
for(int j=0;j<ans[i].accnt;j++)
{
cin>>ans[i].ans[j];
ans[i].a[ans[i].ans[j]]=1;//标记
}
}
for(int i=0;i<n;i++)
{
char temp;
double socore=0;
for(int k=0;k<m;k++)
{
cin>>temp;
int flag[109];
int flag1=0;
int index=0;
memset(flag,0,sizeof(flag));//一定要清空这个lag数组
int z;
cin>>z;
for(int j=0;j<z;j++)
{
cin>>temp;
if(ans[k].a[temp]==0)//如果当前的标记没有出现过,说明是不合法的答案
{
a[k][temp]++;
flag1=1;//标记有不合法的的答案就已经是0分了
}
flag[temp]=1;//标记当前结点已经访问过来
}
if(flag1==0)//如果没有出现错误答案
{
if(z==ans[k].accnt)//如果和正确答案的个个数就相同就是满分
socore+=ans[k].score;
else//如果不相同就是一半的分数
socore+=ans[k].score*1.0/2;
}
for(int k1=0;k1<ans[k].accnt;k1++)//出现错误答案后,说明题目正确答案也没有出现过就是也是错误答案,所以直接也加进去
{
int index=ans[k].ans[k1];
if(flag[index]==0)
{
a[k][index]++;
}
}
getchar();
getchar();
}
socre[i]+=socore;
}
for(int i=0;i<n;i++)
{
printf("%0.1lf\n",socre[i]);
}
int max=-9999;
for(int i=0;i<m;i++)//找到出现次数最多的答案
{
for(int j=0;j<=108;j++)
{
if(a[i][j]>=max)
max=a[i][j];
}
}
if(max==0)
{
cout<<"Too simple"<<endl;
return 0;
}
for(int i=0;i<m;i++)
{
for(int j=0;j<=108;j++)
{
if(a[i][j]==max)
cout<<max<<" "<<i+1<<"-"<<char(j)<<endl;
}
}
return 0;
}