题意:
n*n的格子 将它分成n份大小为n的连通块 要求每个块形状不同 用4种颜色将格子染色后输出
思路:
纯构造题 考验智商 不过还是有思路可寻的
首先这题要想到将格子分区域的去做(想不到就没办法了…)假设我们两行为一个区域 那么将这两行划分成两个面积为n的块之后发现它们的形状必然相同 因此两行不行 所以我们尝试3行为1个区域!! 可以构造:
这样构造就可以保证形状不同 但是绿色会连上!! 那么我们通过奇偶性将图翻转 这样绿色就不会连上了 因为连起来至少需要绿色的外边长为n/2 但我们是3列分1个区域 也就是说绿色外边长最大就是n/3
还有问题 因为n不见得正好被3整除 不整除的时候如果余1就好办(直接加一行纯色的) 余2就麻烦了
如果余2 那么我们需要拆掉上图中的第一个(也就是构造时候绿色边长从2开始) 这时我们共有5行 填一行纯色的 还剩4行 接下来按这样构造:
根据上述构造方法 在n整除3的时候还会出现问题 因为图1中绿色的部分可能变成矩形 导致红色和蓝色形状相同 这时候只要把红色和蓝色其中一个格子换一下就好了 换的方法有很多(只要这两个不对称就行)
还有要注意特判1和5的时候直接构造一个答案输出 2、3、4时候没答案
代码:
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef long long LL;
#define N 110
#define M 400010
#define inf 2147483647
#define lowbit(x) (x&(-x))
char f[N][N]; //RBYG
int main() {
int t, n, i, j, k, flag;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
if (n == 1)
puts("R");
else if (n < 5)
puts("No solution!");
else if (n == 5) {
puts("YYYGR");
puts("YGGGR");
puts("YGYYR");
puts("BYYYR");
puts("BBBBR");
} else {
flag = n / 3;
for (k = n; k > 5; k -= 3, flag--) {
for (i = k; i > k - 3; i--) {
for (j = 1; j <= n; j++)
f[i][j] = 'R';
}
if (flag & 1) {
for (i = k; i > k - 3; i--) {
for (j = n - flag + 1; j <= n; j++)
f[i][j] = 'Y';
}
for (j = flag * 2 + 1; j <= n; j++)
f[k - 1][j] = 'Y';
for (j = flag + 1; j <= flag + flag; j++)
f[k - 1][j] = 'B';
for (j = 1; j <= n - flag; j++)
f[k][j] = 'B';
} else {
for (i = k; i > k - 3; i--) {
for (j = 1; j <= flag; j++)
f[i][j] = 'Y';
}
for (j = 1; j <= n - flag * 2; j++)
f[k - 1][j] = 'Y';
for (j = n - flag - flag + 1; j <= n - flag; j++)
f[k - 1][j] = 'B';
for (j = flag + 1; j <= n; j++)
f[k][j] = 'B';
}
}
if (k > 3) {
for (j = 1; j <= n; j++)
f[k][j] = 'G';
k--;
}
if (k > 3) {
for (i = 1; i <= 4; i++) {
for (j = 1; j <= n; j++)
f[i][j] = 'G';
}
for (i = 1; i <= 4; i++)
f[i][1] = 'R';
for (j = 2; j <= n - 3; j++)
f[4][j] = 'R';
f[4][n - 2] = f[4][n - 1] = f[4][n] = 'B';
for (j = 2; j <= n - 2; j++)
f[3][j] = 'B';
f[3][n - 1] = f[3][n] = 'Y';
for (j = 2; j <= n - 1; j++)
f[2][j] = 'Y';
} else {
for (i = 1; i <= 3; i++) {
for (j = 1; j <= n; j++)
f[i][j] = 'Y';
}
for (j = 1; j <= n - 1; j++)
f[1][j] = 'R';
f[2][1] = 'R';
for (j = 1; j <= n - 1; j++)
f[3][j] = 'B';
f[2][2] = 'B';
}
if (n % 3 == 0) {
flag = n / 3;
if (flag & 1)
swap(f[n - 1][1], f[n - 1][flag + 1]);
else
swap(f[n - 1][n - flag], f[n - 1][n]);
}
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++)
putchar(f[i][j]);
putchar('\n');
}
}
}
return 0;
}