1. 程式人生 > 其它 >LuoguP5594 【XR-4】模擬賽 題解

LuoguP5594 【XR-4】模擬賽 題解

LuoguP5594 【XR-4】模擬賽 題解

Update

  • \(\texttt{2021.6.28}\) 對這篇題解的排版按照最新洛谷題解稽核要求結合自己的題解格式進行了修改,並刪去了一些廢話。
    順便,感謝各位對於這篇題解的大力支援!

Content

請前往原題檢視。

資料範圍:\(1\leqslant m\leqslant n,k\leqslant 10^3\)\(1\leqslant a_{i,1}<a_{i,2}<\dots<a_{i,m}\leqslant k\)

Solution

說實話,在這樣的入門題中使用 \(\texttt{set}\)\(\texttt{vector}\) 確實有點小題大做,而且這種題解一般對於剛學 OI 的萌新來說很不友好。其實沒必要這麼複雜,這道題目只要用一個二維 \(vis\)

陣列即可。 那麼這個 \(vis\) 陣列契機從何而來呢?

我們注意到題目中的這段話:

教練需要為每一個人的每一次模擬賽做準備,為了減小工作量,如果在某一天有多個人打同一套模擬賽題,那麼教練只需要在這一天準備一場使用這一套題的模擬賽即可。

如果你理解了這段話,這道題目就做完一大半了,剩下的就是程式碼實現的問題了。

這就是那個二維 \(vis\) 陣列的作用所在。

設這個陣列中的元素 \(vis_{i,j}\) 表示當 \(vis_{i,j}=1\) 的時候表示第 \(j\) 天已經準備了第 \(i\) 套模擬題,這樣就可以保證只在第一次在第 \(j\) 天需要第 \(i\) 套模擬題的時候統計進去,而且接下來如果還碰到同一天打同一套題目的時候不會重複計算。

每個同學的空閒天也可以用二維陣列 \(a\) 來儲存,至於題目直接用 \(1,2,...,m\) 表示就可以了,不需要再開陣列。

所以這道題目就寫完了。

Code

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int n, m, k, tot[1004], vis[1004][1004], a[1004][1004];

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j)
			scanf("%d", &a[i][j]);
	for(int i = 1; i <= n; ++i) {
		for(int j = 1; j <= m; ++j) {
			if(!vis[j][a[i][j]]) {
				vis[j][a[i][j]] = 1;
				tot[a[i][j]]++;
			}
		}
	}
	for(int i = 1; i <= k; ++i)
		printf("%d ", tot[i]);
	return 0;
}