构造 ZOJ 3810 A Volcanic Island
来源:互联网 发布:js window document 编辑:程序博客网 时间:2024/04/28 00:43
An underwater volcano has erupted massively in somewhere of the deep Atlantis Ocean. This large eruption led to the birth of a new volcanic island, which had a shape of square. Near the island, there are N countries. All of them have claimed the sovereignty over the island.
After a lot of multilateral negotiation and occasional armed conflicts, the N countries decided to divide the square volcanic island equally. They partitioned the island into N x N small equal-sized square chunks. Each country could get a connected region consists of exact N chunks.
Two chunks A and B are called "connected" if they share an edge, or there exists another chunk C connected with both A and B. A group of chunks are called "connected region" if any two of these chunks are connected.
Every country want a unique region. It means the N regions should be different with each other. Two regions are considered as the same if and only if one can transform into the other by an isometry (a combination of rigid motions, including translation, rotation and reflection).
In a nutshell, your task is to divide a square island with N x N chunks into N connected regions with different shape. You also need to draw a map to color the regions of the map so that no two edge-adjacent regions have the same color. Most of the people in these countries believed that four different colors are enough. So you can mark these regions with at most four colors, red, green, blue and yellow.
Input
There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:
There is only an integer N (1 <= N <= 100).
Output
For each test case, output a valid map described above. If there is no solution, output "No solution!" instead. Please note that only four colors ('R', 'G', 'B' and 'Y') can be used to drawing the map.
Sample Input
225
Sample Output
No solution!YYYGRYGGGRYGYYRBYYYRBBBBR
Author: ZHOU, Yuchen
Source: The 2014 ACM-ICPC Asia Mudanjiang Regional First Round
题意:有一个N*N的方格图,每个格子要涂上四种颜色中的一种,如果相邻的颜色相同,他们是同一个区域,现在需要输出一个N*N的方格图,方格图中的所有区域的形状两两不相同,如果翻转和旋转后相同当做是相同的。
思路:一看就知道是构造,但是智商真的是捉急啊,想不到什么好的构造办法,构造题一般是要以一两种特定的方式进行逐步的求解吧。。。感觉是这样,一开始乱来,想着会不会沿着外围走就行了呢?可惜是不行的,后来想到了一个构造方法,就是不断摆出"Z"行,但是发现只能摆n/2个,于是又没想下去了,其实这里已经比较接近答案了。最后还是看了题解才知道....Orz
一个可能的构造形式如下:
10 * 10的时候
BBBBBBBBBY
GGGGGGGGBY
BBBBBBBGGY
GGGGGGBBBY
BBBBBGGGGY
YYYYBBBBBY
BBBYGGGGGY
YYBYYYYYGY
YYBBBBBBGY
YYYYYYGGGY
于是要特判一些n比较小的情况,就行了....
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cassert>#include <queue>#include <vector>#include <map>#include <set>#include <algorithm>using namespace std;#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)#define rrep(i,b,a) for(int i=(b);i>=(int)(a);--i)#define eps 1e-9#define clr(a,x) memset(a,x,sizeof(a))#define LL long longconst int maxn = 200+5;const int Move[2][4] = { {1,0,-1,0},{0,1,0,-1} };char col[] = "YBGR";char ans[maxn][maxn];char color[maxn];bool adj[maxn][maxn];int n;/*形式如下BBBBBBBBBYGGGGGGGGBYBBBBBBBGGYGGGGGGBBBYBBBBBGGGGYYYYYBBBBBYBBBYGGGGGYYYBYYYYYGYYYBBBBBBGYYYYYYYGGGY */bool inRange(int r,int c) { return 0<=r&&r<n&&0<=c&&c<n; }bool vis[maxn][4];int rst[maxn];int S[maxn*maxn],c;bool build_color(int rest){ if (rest == 0) return true; int k = -1; for(int i = 1; i <= n; ++i) if(color[i]==0 && (k == -1 || rst[i] < rst[k])) k = i; if (rst[k] == 0) return false; rep(i,0,4) { if (vis[k][i]) continue; vis[k][i] = true; color[k] = col[i]; int cc = c; rep(j,1,n+1) if (adj[k][j] && !vis[j][i]) { vis[j][i] = true; --rst[j]; S[c++] = j << 2 | i; } if (build_color(rest-1)) return true; vis[k][i] = false; while (c > cc) { int x = S[--c]; vis[x>>2][x&3] = false; ++rst[x>>2]; } } color[k] = 0; return false;}void out(){ puts(""); rep(i,0,n) { rep(j,0,n) printf("%c",ans[i][j]+'0'); puts(""); } puts("");}bool solve(){ if (n == 2 || n == 3 || n == 4) return false; else if(n == 1) { puts("Y"); return true; } else if(n == 6) { puts("YYYYYY"); puts("BBBRRB"); puts("BBBRRB"); puts("RYRRYB"); puts("RYYYYB"); puts("RRRRBB"); return true; } else if (n == 5) { puts("YYYGR"); puts("YGGGR"); puts("YGYYR"); puts("BYYYR"); puts("BBBBR"); return true; } clr(ans,0); int cnt = 1; rep(i,0,n) rep(j,0,n) ans[i][j] = cnt; ++cnt; rep(i,0,n) ans[i][n-1] = cnt; ++cnt; rep(i,0,n/2) { rep(j,0,n-1-i) ans[i][j] = cnt; rep(j,n-2-i,n-1) ans[i+1][j] = cnt; ++cnt; } rep(i,n/2,n) { if (i+2>n-2) break; rep(j,0,n-1-i) ans[i][j] = cnt; ans[i+1][n-2-i] = cnt; rep(j,n-2-i,n-2) ans[i+2][j] = cnt; ++cnt; } int len = 0; rep(j,n-1-n/2,n-1) { ans[n/2+1][j] = cnt; ++len; } rep(i,n/2+2,n) ans[i][n-2] = cnt, ++len; rrep(j,n-3,0) { if(len == n) break; ans[n-1][j] = cnt; ++len; }// out(); clr(adj,0); rep(i,0,n) rep(j,0,n) rep(k,0,4) { int rr = i + Move[0][k]; int cc = j + Move[1][k]; if(!inRange(rr,cc)) continue; int u = ans[i][j],v=ans[rr][cc]; if (u == v) continue; adj[u][v] = adj[v][u] = true; } rep(i,1,n+1) rst[i] = 4; clr(vis,0); c = 0; clr(color,0); build_color(n); rep(i,0,n) rep(j,0,n) { // x = max((int)ans[i][j],x); assert(ans[i][j]<maxn); ans[i][j] = color[ans[i][j]]; } rep(i,0,n) printf("%s\n",ans[i]); return true;}int main(){ int T; cin >> T; while (T--) { scanf("%d",&n); if (!solve()) puts("No solution!"); }}
- ZOJ 3810 A Volcanic Island 构造题
- zoj 3810 A Volcanic Island(构造)
- [ZOJ 3810 A Volcanic Island] 构造+调整
- 构造 ZOJ 3810 A Volcanic Island
- ZOJ - 3810 A Volcanic Island 构造
- ZOJ 3810 A Volcanic Island
- zoj 3810 A Volcanic Island
- zoj 3810 A Volcanic Island
- ZOJ 3810 A Volcanic Island
- zoj 3810 A Volcanic Island 构造不同图形
- ZOJ 3810 A Volcanic Island(四色定理模板)
- ZOJ 3810 A Volcanic Island (2014年牡丹江赛区网络赛B题)
- zoj3810——A Volcanic Island (四色定理)
- ZOJ3810--A Volcanic Island(四色定理模板)
- zoj 3500 island communication
- zoj 3509 Island Communication
- zoj 2254 - Island Country
- ZOJ 1638 Greedy Island
- Spring中装配集合
- 2014年最新申请IDP账号的过程(含DUNS申请方法)
- 0034算法笔记——【分支限界法】最优装载问题
- Spring中自动装配
- 第一篇文章,关于Sprite的深度排序
- 构造 ZOJ 3810 A Volcanic Island
- 利用反射控制AlertDialog,使其不自动关闭
- 数据结构之绪论
- TFS源码解析一
- Spring中bean的作用域与bean的初始化与销毁
- OAuth2.0的refresh token
- myeclipse中properties文件
- 山东矿机回复你就看电视
- neu1132(增量最小生成树,两点之间的最大边权)