1. 程式人生 > 其它 >1058 選擇題 (20 point(s))

1058 選擇題 (20 point(s))

#include <bits/stdc++.h>
using namespace std;

struct Question{
	int score, num, cor;
	set<char> copt;
};

int main() {
	// 批改選擇題 指出錯誤人數最多題目
	// 輸入 學生人數 多選題個數
	int n, m;
	vector<Question> qt;
	cin >> n >> m; 
	
	// M行給出 
	// 滿分值≤5 2≤選項個數≤5 ≥ 正確選項個數 正確選項
	// 選項 a- 
	for(int i = 0; i < m; i++){
		int score, num, cor;
		Question tmp;
		cin >> score >> num >> cor;
		tmp = {score, num, cor};
		// 迴圈插入正確選項 
		while(cor--){
			char c;
			cin >> c; 
			tmp.copt.insert(c);
		}
			
		// 全部輸入完之後存入題目 
		qt.push_back(tmp);
	}
	 
	// N行給出 
	// 記錄錯題人數
	int fault[m]{0}; 
	while(n--){
		// 遍歷每個題目 初始化成績 題目編號  
		int sum = 0, i = 0;
		for(auto q : qt){
			int num, all = 0, flag = true;
			char c;
			// 吃掉沒意義的括號 讀取 答題選項數量 
			cin >> c >> num;
			
			// 有選項的時候執行 
			while(num--){
				// 讀取選中選項(按題序給出
				cin >> c;
				// 有一個題錯誤不得分  
				if(q.copt.find(c) == q.copt.end())
					flag = false;
				// 字元選項需要全部錄入 否則會多出字元導致後面錯誤
				
				// 第一題++
				all++; 
			}
				
			// 沒選中全部不得分 
			if(all != q.cor) flag = false;
			 
			// 全部正確才得分
			if(flag) sum += q.score;
			// 統計錯題 
			else fault[i]++;
			
			// 吃掉沒意義的括號
			cin >> c;
			
			//指向下一題
			i++; 
		} 
		
		// 每個人最後直接評出分數
		cout << sum << endl; 
	}
	
	// 找出最大值
	int max = *max_element(fault, fault + m);
	
	// 沒有人錯誤  Too simple
	if(max == 0) cout << "Too simple";
	// 並列 空格分割 編號遞增輸出 一次次數 多個編號
	else{
		cout << max; 
		int i = 1;
		for(auto f: fault){
			// 編號 1開始
			if(f == max)
				cout << " " << i;
			//指向下一題 
			i++;
		}
	}
}

程式碼有點長,寫了有點久75min左右,前面犯了一些問題,自己定義的變數和題目要求的沒能夠明確清楚,導致卡了十分鐘左右。所以多寫寫註釋或者在草稿紙上面明確下還是很有必要的,多理解下題目和裡面的變數。

不然多看兩眼或者寫一兩行字也就一兩分鐘,但是找bug找十分鐘。顯然得不償失。

中間判斷正確也卡了一下,剛開始只記得要判斷學生的選項有沒有選對,但是題目還有一個條件就是“全部正確才能得到該題的分數”,所以不僅僅是學生還有題目的正確選項需要考慮。

剛開始想複雜了,還想著要遍歷全部正確選項然後對著學生的選項。但後面想了想完全沒必要,因為已經給出了正確選項的個數(寫的時候一時忘記了),只需要宣告一個變數記錄學生正確個數,對比題目正確選項個數即可。

除了模擬過程中繁瑣了一點,但是把所有都搞定之後直接就全AC了。關鍵還是在某些細節上面卡了不少時間。雖然有在程式碼裡面先照著題目給出大體的思路,但是具體的實現沒有明確清楚,比如題目編號的因為題目沒有給出,還得自己記錄一下,當時當時沒有明確到底在那個程式碼塊 {} 大括號裡面宣告變數,又應該在哪裡變更變數指向下一題,所以又花了點時間試錯改正。

或者就像剛開始弄錯變數導致除錯,或者是中間的判讀選項正確。這些如果能夠在草稿上面進一步明確處理的方式,可能可以節省不少時間。至少進一步推導也能夠明確自己能否解決這個問題,是否在具體過程中存在某些無法解決的,自己又難以給出方法的細節問題。這時候就可以跳過不管,直接下一題了。而不需要在實現的時候才發現有問題,但這時候已經浪費不少時間了。

在解題上,我們先判斷這題目是有難度的,比如像螺旋矩陣那題,一看到題目的條件我們去嘗試給出自己的思路,是否能夠想到什麼解決的方法,是否能夠想起有什麼類似的解題思路。如果很陌生的,或者覺得給出的資料很複雜的,就應該判斷這題目是具有一定難度的,不像一般的題目一兩個過程就能夠解決的。

對於這類題目,就應該在草稿紙上先嚐試給出具體過程的實現,嘗試檢查題目給出的所有條件,將這種複雜問題具體化明確化。就算髮現具體實現給不出,也能夠快速反應過來,感覺去做那些可以做的題目,而不用白費時間在上面。


讀取題目資訊的時候,因為包含一個容器,所以可以對結構體一部分變數進行賦值,如下。

tmp = {score, num, cor};

然後再對剩下的容器讀取元素。


cin >> c 開始的時候忘記寫這個東西了,而且因為沒有正確明確變數把 while(cor--) 讀取正確選項弄成了 num,全部選項個數。導致了 Running Error 。

不過如果是不讀取 cin 的話,其實就算輸入了也不會卡住的,直接就跳過你的輸入繼續執行下面的程式碼了。但是如果讀取了錯誤的迴圈變數,導致迴圈變數沒有正確執行的話,就會變成死迴圈導致 Running Error 。

所以以後出現這個評測錯誤的時候,應該注意自己的迴圈退出迴圈條件是不是寫錯了。