Codeforces 1869C Fill in the Matrix

题目来自 Codeforces Round #896 (Div.2) C。link


  This article provides a feasible solution to a certain competitive programming problem.   If you have better solutions, feel free to share with me!


Problem Description

The MEX of an array is the smallest non-negative integer that does not belong to the array. e.g., MEX(0,3,1,4)=2 because 2 does not belong to the array.

n×m (ni×mi2×106) 的矩阵 M,要求填满这一矩阵,使得:

  • 矩阵的每一行是一个长为 m 的排列 (0m1)。
  • 定义该矩阵每一列的 value vi=MEX(M1,i,M2,i,...,Mn,i),最大化 s=MEX(v1,v2,...,vm)


Tutorial

MEX 函数的一个重要性质:MEX(arr) 的值不仅与 arr 数组的值有关,还与 arr 数组的长度有关。

  • arr 数组的最大值为 c,则 MEX(arr)c+1
  • arr 数组的长度为 d,则 MEX(arr)d

根据这一性质,我们能够得到 s 的 upper bound:

  • vi=MEX(M1,i,...,Mn,i)n, (n{vi} 的最大值) 因此 sn+1
  • s=MEX(v1,v2,...,vm), sm.

因此 mn+1s 的上界的两种形式;s 将被较小的上界限制。

n+1m 时,s=n+1

被 n+1 上界限制

n+1>m 时,s=m

被 m 上界限制


Code Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>

using namespace std;

int main() {

int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
if (n + 1 <= m) {
cout << n + 1 << endl;
for (int i = 1; i <= n; ++i) {
for (int j = i; j <= i + n; ++j) {
cout << j % (n + 1) << " ";
}
for (int j = n + 1; j < m; ++j) {
if (j == m - 1)
cout << j << "\n";
else
cout << j << " ";
}
}
} else {
if (m == 1)
cout << "0" << endl;
else
cout << m << endl;
for (int i = 1; i <= m - 1; ++i) {
for (int j = i; j <= i + m - 1; ++j) {
if (j == i + m - 1)
cout << j % m << "\n";
else
cout << j % m << " ";
}
}
for (int i = 1; i <= n - m + 1; ++i) {
for (int j = 1; j <= m; ++j) {
if (j == m)
cout << 0 << "\n";
else
cout << j << " ";
}
}
}
}

return 0;
}


-----------------------------------そして、次の曲が始まるのです。-----------------------------------