题目链接:https://ac.nowcoder.com/acm/contest/5671/G
题目大意
给你一个(n imes n)的矩阵,对其边进行染色,染色条件需要满足:
- 需要使用
- 图中不能够有单色环
- 任意连着的一行,一列不能是单色(至少两种颜色)。
当存在这样的构造时,先输出(n+1)行水平的边的颜色,再输出(n+1)列垂直边的颜色。
若不存在这样的构造,则输出(-1)。
思路
构造题。
首先判断是否存在构造。当(n=1)时,不能满足条件3,当(k=1)时,不能满足条件2和3,当((2*n*(n+1))quad mod quad k eq0)时,不能满足条件1。对以上三种情况进行特判,输出(-1)。
然后将行和列提取出来,将行构成一个((n+1)*n)的表,将列构成一个(n*(n+1))的表。如下图所示,黄色的为要填写数字的水平线,粉色的为要填写数字的垂直线。
由条件3可知,黄色表格的每一行在对(k)取模后,不能相同,粉色表格的每一列在对(k)取模后,不能相同。
同时发现,若要满足条件2,可以从两张表格中有对应的位置关系,例如:
即在这四个位置,需要满足对(k)取模后,不能相同。
考虑蚯蚓蛇形构造,如下图所示:
发现在任意中,都会出现一段连续的线段。
连续的线段意味着,此处填入的数字较上一位(+1)。
当(n%geqslant 2)时,容易证明(i quad mod quad n quad
eq quad (i+1) quad mod quad n)。
对于奇偶不同的(n),分类讨论即可。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf_int 0x3f3f3f3f
#define inf_ll 0x3f3f3f3f3f3f3f3f
const int MAXN = 205;
int row[MAXN][MAXN];
int col[MAXN][MAXN];
int main() {
int T;
scanf("%d", &T);
while (T--) {
int n, k;
scanf("%d%d", &n, &k);
int sum = 2 * n * (n + 1);
if (sum % k != 0 || n == 1 || k == 1) {
printf("-1
");
continue;
}
int cnt = 0;
if (n & 1) {
for (int i = 1; i < n; i += 2) {
for (int j = 1; j <= n + 1; j++) {
if (j & 1) {
row[j][i] = cnt++;
row[j][i + 1] = cnt++;
} else {
row[j][i + 1] = cnt++;
row[j][i] = cnt++;
}
}
}
for (int i = 1; i <= n + 1; i++) {
row[i][n] = cnt++;
}
for (int i = 1; i <= n + 1; i++) {
col[1][i] = cnt++;
}
for (int i = 2; i <= n; i += 2) {
for (int j = 1; j <= n + 1; j++) {
if (j & 1) {
col[i][j] = cnt++;
col[i + 1][j] = cnt++;
} else {
col[i + 1][j] = cnt++;
col[i][j] = cnt++;
}
}
}
for (int i = 1; i <= n + 1; i++) {
for (int j = 1; j <= n; j++) {
printf("%d ", row[i][j] % k + 1);
}
printf("
");
}
for (int i = 1; i <= n + 1; i++) {
for (int j = 1; j <= n; j++) {
printf("%d ", col[j][i] % k + 1);
}
printf("
");
}
} else {
for (int i = 1; i < n; i += 2) {
for (int j = 1; j <= n + 1; j++) {
if (j & 1) {
row[j][i] = cnt++;
row[j][i + 1] = cnt++;
} else {
row[j][i + 1] = cnt++;
row[j][i] = cnt++;
}
}
}
for (int i = 1; i <= n; i += 2) {
for (int j = 1; j <= n + 1; j++) {
if (j & 1) {
col[i + 1][j] = cnt++;
col[i][j] = cnt++;
} else {
col[i][j] = cnt++;
col[i + 1][j] = cnt++;
}
}
}
for (int i = 1; i <= n + 1; i++) {
for (int j = 1; j <= n; j++) {
printf("%d ", row[i][j] % k + 1);
}
printf("
");
}
for (int i = 1; i <= n + 1; i++) {
for (int j = 1; j <= n; j++) {
printf("%d ", col[j][i] % k + 1);
}
printf("
");
}
}
}
}