1073 多选题常见计分法 逻辑题

陌陌的pat乙级题解

题解

逻辑题
确实感觉我写的有点麻烦,不过感觉还算比较好理解
首先要知道的是:错误选择是指 错选 和 漏选(正确的不够)
我的数据结构:
1. 两个二维数组,记录错的次数 和 正确性
2. 一个map<int,set> 记录每道题的正确答案,目的是为了判断漏选

Code

#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
	int N, M;
	cin >> N >> M;
	// error_cnt[i][j] i题j项错的cnt
	// Right[i][j] 是否是对的
	vector<vector<int>> error_cnt(M + 5, vector<int>(130)), Right(M + 5, vector<int>(130));
	// 每道题的正确答案
	map<int, set<char>> rap;
	for (int i = 1; i <= M; i++)
	{
		int x, y, k;
		cin >> x >> y >> k;
		// 利用Right的三个空间来保存一些数据
		// 反正选项是'a' - 'z',也用不到
		// 分数
		Right[i][0] = x;
		// option cnt
		Right[i][1] = y;
		// right cnt
		Right[i][2] = k;
		char t;
		while (k--)
		{
			cin >> t;
			rap[i].insert(t);
			Right[i][t] = 1;
		}
	}
	int maxt = -1;
	while (N--)
	{
		char t;
		int k;
		char x;
		double sum = 0;
		for (int i = 1; i <= M; i++)
		{
			cin >> t >> k;
			// 标记是否选了错误的
			bool f = true;
			// 用来判断漏选的,把正确选的加进去
			set<char> ret;
			while (k--)
			{
				cin >> x;
				if (Right[i][x] == 1)
				{
					ret.insert(x);
				}
				else
				{
					f = false;
					// 选错误的option
					error_cnt[i][x]++;
					// 找错误最大的
					maxt = max(maxt, error_cnt[i][x]);
				}
			}
			// 看正确选项有没有漏选
			for (auto e : rap[i])
			{
				// 已经选择的正确选择,找不到就是漏选
				if (ret.count(e) == 0)
				{
					error_cnt[i][e]++;
					maxt = max(maxt, error_cnt[i][e]);
				}
			}
			cin >> t;
			// 直接全错
			if (f == false)
			{
				continue;
			} // 没有错,对的不全
			else if (ret.size() != Right[i][2] && ret.size() > 0)
			{
				sum += 1.0 * Right[i][0] / 2;
			}
			// 对的全
			else if (ret.size() == Right[i][2])
			{
				sum += Right[i][0];
			}
		}
		printf("%.1f\n", sum);
	}
	if (maxt == -1)
	{
		cout << "Too simple\n";
	}
	else// 扫描一遍
		for (int i = 1; i <= M; i++)
		{
			for (int j = 'a'; j <= 'z'; j++)
			{
				if (error_cnt[i][j] == maxt)
				{
					cout << maxt << " " << i << "-" << (char)j << endl;
				}
			}
		}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值