首页 > 代码库 > ZOJ 3810 A Volcanic Island
ZOJ 3810 A Volcanic Island
题意:
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; }
ZOJ 3810 A Volcanic Island
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。