noip模拟赛 c
分析:一道比较难的爆搜题.首先要把9个块的信息存下来,记录每个块上下左右位置的颜色,然后记录每一排每一列能否操作,之后就是bfs了。在bfs的时候用一个数记录状态,第i位表示原来的第i个块现在在哪个位置,我们可以通过这个状态来解码得到信息,也可以来判重,只是数组开不下,需要用一个map。然后就是如何判断是否连通.首先把所有块还原成一张图,然后我们可以数每个颜色连通的数量,看看是不是等于36就可以了,这里用dfs来判断.
学习了一种比较强的记录状态的方式:记录相对位置,既可以判重,也可以还原图.
#include <cstdio> #include <map> #include <queue> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int canx[5], cany[5], zhuangtai[10]; int can[5], vis[10][10], a[10][10]; map <long long, int> flag; struct node { int col[5]; }e[10]; struct node2 { long long stu; int dist; }; long long hashh(int a, int b, int c, int d, int e, int f, int g, int h, int i) { return (((((((a * 10 + b) * 10 + c) * 10 + d) * 10 + e) * 10 + f) * 10 + g) * 10 + h) * 10 + i; } int dfs(int col, int x, int y, int last) { //printf("%d %d %d %d\n", col, x, y, last); int ret = 0; if (vis[x][y] || (a[x][y] != col && a[x][y] != 0) || (a[x][y] == 0 && last == 0)) return ret; vis[x][y] = 1; if (col == a[x][y]) ret++; if (x > 0) ret += dfs(col, x - 1, y, a[x][y]); if (x < 8) ret += dfs(col, x + 1, y, a[x][y]); if (y > 0) ret += dfs(col, x, y - 1, a[x][y]); if (y < 8) ret += dfs(col, x, y + 1, a[x][y]); return ret; } bool check(long long stu) { //printf("%lld\n", stu); int res = 0; memset(can, 0, sizeof(can)); memset(a, 0, sizeof(a)); for (int i = 2; i >= 0; i--) for (int j = 2; j >= 0; j--) { int x = stu % 10; a[i * 3][j * 3 + 1] = e[x].col[0]; a[i * 3 + 2][j * 3 + 1] = e[x].col[1]; a[i * 3 + 1][j * 3] = e[x].col[2]; a[i * 3 + 1][j * 3 + 1] = e[x].col[3]; stu /= 10; } for (int i = 0; i <= 8; i++) { for (int j = 0; j <= 8; j++) printf("%d ", a[i][j]); printf("\n"); } printf("\n"); for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) for (int k = 1; k <= 4; k++) if (!can[k] && a[i][j] == k) { memset(vis, 0, sizeof(vis)); res += dfs(k, i, j, 0); can[k] = 1; } if (res == 36) return true; return false; } void bfs() { queue <node2> q; node2 temp; temp.stu = 12345678; temp.dist = 0; q.push(temp); flag[12345678] = 1; while (!q.empty()) { node2 u = q.front(); q.pop(); long long stu = u.stu; int dist = u.dist; //printf("%lld %d\n", stu, dist); if (check(stu)) { printf("%d\n", dist); return; } //printf("flag\n"); for (int i = 8; i >= 0; i--) { zhuangtai[i] = stu % 10; stu /= 10; } if (!canx[0]) { long long nstu = hashh(zhuangtai[1], zhuangtai[2], zhuangtai[0], zhuangtai[3], zhuangtai[4], zhuangtai[5], zhuangtai[6], zhuangtai[7], zhuangtai[8]); //printf("%lld\n", nstu); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } nstu = hashh(zhuangtai[2], zhuangtai[0], zhuangtai[1], zhuangtai[3], zhuangtai[4], zhuangtai[5], zhuangtai[6], zhuangtai[7], zhuangtai[8]); //printf("%lld\n", nstu); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } } if (!canx[1]) { long long nstu = hashh(zhuangtai[0], zhuangtai[1], zhuangtai[2], zhuangtai[4], zhuangtai[5], zhuangtai[3], zhuangtai[6], zhuangtai[7], zhuangtai[8]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } nstu = hashh(zhuangtai[0], zhuangtai[1], zhuangtai[2], zhuangtai[5], zhuangtai[3], zhuangtai[4], zhuangtai[6], zhuangtai[7], zhuangtai[8]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } } if (!canx[2]) { long long nstu = hashh(zhuangtai[0], zhuangtai[1], zhuangtai[2], zhuangtai[3], zhuangtai[4], zhuangtai[5], zhuangtai[7], zhuangtai[8], zhuangtai[6]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } nstu = hashh(zhuangtai[0], zhuangtai[1], zhuangtai[2], zhuangtai[3], zhuangtai[4], zhuangtai[5], zhuangtai[8], zhuangtai[6], zhuangtai[7]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } } if (!cany[0]) { long long nstu = hashh(zhuangtai[3], zhuangtai[1], zhuangtai[2], zhuangtai[6], zhuangtai[4], zhuangtai[5], zhuangtai[0], zhuangtai[7], zhuangtai[8]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } nstu = hashh(zhuangtai[6], zhuangtai[1], zhuangtai[2], zhuangtai[0], zhuangtai[4], zhuangtai[5], zhuangtai[3], zhuangtai[7], zhuangtai[8]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } } if (!cany[1]) { long long nstu = hashh(zhuangtai[0], zhuangtai[4], zhuangtai[2], zhuangtai[3], zhuangtai[7], zhuangtai[5], zhuangtai[6], zhuangtai[1], zhuangtai[8]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } nstu = hashh(zhuangtai[0], zhuangtai[7], zhuangtai[2], zhuangtai[3], zhuangtai[1], zhuangtai[5], zhuangtai[6], zhuangtai[4], zhuangtai[8]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } } if (!cany[2]) { long long nstu = hashh(zhuangtai[0], zhuangtai[1], zhuangtai[5], zhuangtai[3], zhuangtai[4], zhuangtai[8], zhuangtai[6], zhuangtai[7], zhuangtai[2]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } nstu = hashh(zhuangtai[0], zhuangtai[1], zhuangtai[8], zhuangtai[3], zhuangtai[4], zhuangtai[2], zhuangtai[6], zhuangtai[7], zhuangtai[5]); if (!flag[nstu]) { node2 temp; temp.stu = nstu; temp.dist = dist + 1; q.push(temp); } } } } void init() { for (int i = 0; i < 9; i++) { int t; for (int j = 0; j < 4; j++) { char ch; cin >> ch; if (ch == 'R') e[i].col[j] = 1; if (ch == 'G') e[i].col[j] = 2; if (ch == 'B') e[i].col[j] = 3; if (ch == 'O') e[i].col[j] = 4; } cin >> t; if (t == 1) { canx[i / 3] = 1; cany[i % 3] = 1; } } } int main() { init(); bfs(); return 0; }