#include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
struct question{ //多选题结构体
int id; //多选题id,从0开始
int weight; //分值
int allOptionNumber; //总选项数量
int rightOptionNumber; //正确选项数量
set<char> rightOption; //正确的选项
int wrongCount; //犯错数量
}qu[100];
struct answerToQuestion{ //一道多选题的答案
int optionNumber; //选项数量
set<char> option; //具体选项
};
bool isRight(question a, answerToQuestion b){ //判断一道题是否正确
bool flag = true; //默认正确
if(a.rightOptionNumber == b.optionNumber){ //先看选项数量对不对
for(set<char>::iterator it = a.rightOption.begin(); it != a.rightOption.end(); it++){
if(b.option.find(*it) == b.option.end()){
flag = false;
break;
} //依次检查每一个选项
}
return flag;
}
return false;
}
bool cmp(question a, question b){ //按错的人数给多选题排序
if(a.wrongCount != b.wrongCount) return a.wrongCount > b.wrongCount;
else return a.id < b.id;
}
int main(){
int n, m;
char c[20], c1;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){ //把所有的多选题读进qu数组
qu[i].id = i;
qu[i].wrongCount = 0;
scanf("%d%d%d", &qu[i].weight, &qu[i].allOptionNumber, &qu[i].rightOptionNumber);
for(int j = 0; j < qu[i].rightOptionNumber; j++){
scanf("%s", c);
qu[i].rightOption.insert(c[0]);
}
}
int stu[n] = {0}; //所有学生的分数默认为0
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
answerToQuestion ans;
c1 = getchar();
while(c1 != ')'){
if(c1 == '(') scanf("%[^)]", c), c1 = getchar();
else c1 = getchar();
}
ans.optionNumber = c[0] - '0'; //c字符串内含有改题目的分值和正确选项
for(int k = 0; k < ans.optionNumber; k++) ans.option.insert(c[2 * k + 2]);
if(isRight(qu[j], ans)) stu[i] += qu[j].weight; //做对了就加分
else qu[j].wrongCount++; //做错了就把做错该题的人加一
}
}
sort(qu, qu + m, cmp); //多选题排序
int maxWrong = qu[0].wrongCount; //错的最多的人数
for(int i = 0; i < n; i++) printf("%d\n", stu[i]); //输出分数
if(maxWrong){
printf("%d", maxWrong);
for(int i = 0; i < m; i++){
if(qu[i].wrongCount == maxWrong) printf(" %d", qu[i].id + 1);
else break;
}
}else printf("Too simple");
return 0;
}
PAT乙级1058 选择题
最新推荐文章于 2024-07-12 10:56:01 发布