补题

2020牛客暑期训练营

第六场 G

在这里插入图片描述
在这里插入图片描述

#include <algorithm>
#include <cstdio>
#include <cstring>

int main() {
  int te; scanf("%d", &te);
  while (te--) {
    int n, k;
    scanf("%d %d", &n, &k);
    if (n == 1 || (2 * n * (n + 1)) % k != 0 || k == 1) {
      puts("-1");
      continue;
    }
    if (n % k == 0) {
      int c = 0;
      for (int i = 1; i <= 2 * (n + 1); ++i) {
        int last = c;
        for (int j = 1; j <= n; ++j) {
          last = last % k + 1;
          printf("%d%c", last, " \n"[j == n]);
        }
        c ^= 1;
      }
    } else {
      int last = 0;
      for (int i = 1; i <= 2 * (n + 1); ++i)
        for (int j = 1; j <= n; ++j) {
          last = last % k + 1;
          printf("%d%c", last, " \n"[j == n]);
        }
    }
  }
  return 0;
}

先特判无解的情况,
注意到一个同色的环中必然存在一条边 ,使得它与 或 同色。
所以我们只需要保证同行 / 列没有两条相邻的边,且相邻两行 / 列同一列 / 行的边颜色不相同。
这是很好构造的,对于 ,直接按 顺序依次分配边权;对于 ,在偶数行 / 列上循环移 1 位即可。
时间复杂度是 。

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页