【2020牛客多校6-G】Grid Coloring(构造)

题目链接:https://ac.nowcoder.com/acm/contest/5671/G

题目大意

给你一个\(n\times n\)的矩阵,对其边进行染色,染色条件需要满足:

  1. 需要使用
  2. 图中不能够有单色环
  3. 任意连着的一行,一列不能是单色(至少两种颜色)。

当存在这样的构造时,先输出\(n+1\)行水平的边的颜色,再输出\(n+1\)列垂直边的颜色。
若不存在这样的构造,则输出\(-1\)

思路

构造题。

首先判断是否存在构造。当\(n=1\)时,不能满足条件3,当\(k=1\)时,不能满足条件2和3,当\((2*n*(n+1))\quad mod \quad k\neq0\)时,不能满足条件1。对以上三种情况进行特判,输出\(-1\)

然后将行和列提取出来,将行构成一个\((n+1)*n\)的表,将列构成一个\(n*(n+1)\)的表。如下图所示,黄色的为要填写数字的水平线,粉色的为要填写数字的垂直线。

由条件3可知,黄色表格的每一行在对\(k\)取模后,不能相同,粉色表格的每一列在对\(k\)取模后,不能相同。

同时发现,若要满足条件2,可以从两张表格中有对应的位置关系,例如:

即在这四个位置,需要满足对\(k\)取模后,不能相同。

考虑蚯蚓蛇形构造,如下图所示:

发现在任意中,都会出现一段连续的线段。
连续的线段意味着,此处填入的数字较上一位\(+1\)
\(n%\geqslant 2\)时,容易证明\(i \quad mod \quad n \quad \neq \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\n");
            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("\n");
            }
            for (int i = 1; i <= n + 1; i++) {
                for (int j = 1; j <= n; j++) {
                    printf("%d ", col[j][i] % k + 1);
                }
                printf("\n");
            }
        } 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("\n");
            }
            for (int i = 1; i <= n + 1; i++) {
                for (int j = 1; j <= n; j++) {
                    printf("%d ", col[j][i] % k + 1);
                }
                printf("\n");
            }
        }

    }
}
posted @ 2020-07-27 18:10  tudouuuuu  阅读(234)  评论(0编辑  收藏  举报