1073 多选题常见计分法 (20 分)

我TM再也不想做这种题了!!!

写完大体思路后忽然发现居然漏掉了“选项漏选”的这种情况,emmmm不管说什么都表达不了我的愤怒,估计我这种写法是全网最最最蠢的写法了…

这道题简直治好了我多年的低血压#$%&#^#
#include<bits/stdc++.h>
using namespace std;
struct question {
	int val,num,ri_num;
	set<char> ans;
	map<char,int> x_wrong;
	/*
		val: 满分值
		num: 选项个数
		ri_num: 选项个数
		set<char> ans: 所有正确选项
		map<char,int> x_wrong: 记录题目选项错的次数
	*/
};
int main() {
	int n,m,max_cnt=0;
	/*
		n: 学生人数
		m: 多选题的个数
		max_cnt: 错的最多的选项的次数
	*/
	cin>>n>>m;
	vector<question> Q(m);
	for(int i=0; i<m; i++) { // 输入题目的数据
		char x;
		cin>>Q[i].val>>Q[i].num>>Q[i].ri_num;
		for(int j=0; j<Q[i].ri_num; j++) {
			cin>>x;
			Q[i].ans.insert(x);
		}
	}
	for(int i=0; i<n; i++) { // 输入学生的答题细节
		scanf("\n");
		int n_num;	//选中的选项个数 
		double grade=0; //学生的成绩
		char x; // 选项
		for(int j=0; j<m; j++) { // 输入每名学生作答的每个题目
			if(j>0) scanf(" ");
			int flag=0; // 判断该题目的学生作答是否正确  0√, 1X
			set<char> xuan; //学生选择的所有选项
			scanf("(%d",&n_num);
			for(int k=0; k<n_num; k++) { // 每个选项
				scanf(" %c",&x);
				xuan.insert(x);
				if(Q[j].ans.find(x)==Q[j].ans.end()) { //选项错误
					flag=1;
					Q[j].x_wrong[x]++;
					max_cnt=Q[j].x_wrong[x]>max_cnt?Q[j].x_wrong[x]:max_cnt;
				}
			} //for-k
			scanf(")");
			for(auto it=Q[j].ans.begin(); it!=Q[j].ans.end(); it++) { //找漏选的
				if(xuan.find(*it)==xuan.end()) { 
				/*某个正确的选项没有选 注意这里没有 flag=1,
				因为没选上不代表此题的答案全错,只有错选才没分*/ 
					Q[j].x_wrong[*it]++;
					max_cnt=Q[j].x_wrong[*it]>max_cnt?Q[j].x_wrong[*it]:max_cnt;
				}
			}
			if(n_num==Q[j].ri_num&&flag==0) grade+=Q[j].val;
			if(n_num<Q[j].ri_num&&flag==0) grade+=1.0*Q[j].val/2;
		} //for-j
		printf("%.1f\n",grade);
	} //for-i
	if(max_cnt==0) {
		cout<<"Too simple";
		return 0;
	}
	for(int i=0; i<m; i++) {
		for(auto it=Q[i].x_wrong.begin(); it!=Q[i].x_wrong.end(); it++) {
			if(it->second==max_cnt)
				cout<<max_cnt<<" "<<i+1<<"-"<<it->first<<endl;
		}
	}
	return 0;
}

回头再看看柳婼的解法,那个按位异或简直酷毙了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值