//疯狂TLE,知道了用了不太准确的hash才250ms过了 //发现此题其实对hash的要求并不是太高,因为它只要找到可行解即可。 /* *State: POJ3732 Accepted 3736K 250MS G++ 3639B *题目大意: * 给定一个r*c的矩阵,r跟c均<=4,然后每个方格有[0,19]种颜色, * 规定可以任选一个方格改变随意的颜色,但是与其相邻的方格的 * 颜色也同时随之改变,上下左右为相邻,求最小步数使矩阵最后 * 均变为0. *解题思路: * 直接用IDA*,注意剪枝。 *解题感想; * 用了IDA*之后一直TLE,因为我自己写挫了的原因吧。之后迫于无奈, * 用了不太准确的hash,真是麻烦啊。 */
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <utility> 7 #include <bitset> 8 #define FF(i, n) for(int i = 0; i < n; i++) 9 #define FOR(i, a, n) for(int i = a; i < n; i++) 10 #define viewPP(a,n,m) {puts("---");FF(i,n){FF(j,m) cout<<a[i][j] <<' ';puts("");}} 11 //一维作为试用版 12 #define viewP(a, n) {FF(i, n) {cout<<a[i]<<" ";} puts("");} 13 using namespace std; 14 15 const int MAXN = 5; 16 const int hinf = 0x3f3f3f3f; 17 const int COR = 20; 18 19 typedef struct _map { 20 int d[MAXN][MAXN]; 21 }M; 22 int r, c, deapth, sol; 23 24 //颜色0~19 25 bool judge_bfs(int x, int y) { 26 if(x >= 0 && x < r && y >= 0 && y < c) 27 return true; 28 return false; 29 } 30 31 int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; 32 33 //pcol为原来的col 34 void floorFill(M &gra, int x, int y, int c, int pcol) { 35 gra.d[x][y] = c; 36 int nx, ny; 37 FF(i, 4) { 38 nx = x + dir[i][0], ny = y + dir[i][1]; 39 if(judge_bfs(nx, ny) && gra.d[nx][ny] == pcol) { 40 floorFill(gra, nx, ny, c, pcol); 41 } 42 } 43 } 44 45 bool is_zero(const M &gra) { 46 FF(i, r) 47 FF(j, c) { 48 if(gra.d[i][j]) 49 return false; 50 } 51 return true; 52 } 53 54 int get_col(M gra) { 55 int tmp[COR] = {0}, cnt = 0; 56 FF(i, r) 57 FF(j, c) { 58 if(!tmp[gra.d[i][j]] && gra.d[i][j] != 0) { 59 tmp[gra.d[i][j]] = 1; 60 cnt++; 61 } 62 } 63 return cnt; 64 } 65 66 struct _path { 67 int x, y, col; 68 }path[1005]; 69 70 //相邻颜色 71 void has_col(const M &gra, int x, int y, bool has[]) { 72 FF(i, COR) has[i]=false; 73 int nx, ny; 74 FF(k, 4) { 75 nx = x + dir[k][0]; 76 ny = y + dir[k][1]; 77 if(judge_bfs(nx, ny) && !has[gra.d[nx][ny]]) 78 has[gra.d[nx][ny]] = true; 79 } 80 return ; 81 } 82 83 bitset<1000024> bvst[25]; 84 int my_zip(const M &gra) { 85 unsigned __int64 z = 0; 86 FF(i, r) 87 FF(j, c) { 88 z = gra.d[i][j] + z * 131; 89 } 90 return (int)(z % 1000007); 91 } 92 93 void dfs(M gra, int step) { 94 if(step > deapth) 95 return ; 96 //viewPP(gra.d, r, c); 97 98 if(is_zero(gra)) { 99 sol = step; 100 printf("%d\n", sol); 101 FOR(i, 1, step+1) 102 printf("%d %d %d\n", path[i].x, path[i].y, path[i].col); 103 return ; 104 } 105 106 int recol = get_col(gra); 107 if(step + recol > deapth) 108 return ; 109 110 FF(i, r) { 111 FF(j, c) { 112 FF(k, COR) { 113 if(sol != -hinf) return ; 114 115 if(k == gra.d[i][j]) continue; 116 bool color[COR]; 117 has_col(gra, i, j, color);//color标志其邻居的颜色 118 if(!color[k] && k != 0) continue;//变为相邻颜色,或者0 119 120 M tmp = gra; 121 //用广搜 122 //3732 Accepted 3768K 4219MS G++ 3709B 123 //update(tmp, i, j, k); 124 //用深搜 125 //3732 Accepted 3736K 250MS G++ 3639B 126 floorFill(tmp, i, j, k, gra.d[i][j]); 127 int t = my_zip(tmp); 128 if(bvst[step+1][t]) continue; 129 bvst[step+1][t] = true; 130 131 path[step+1].x = i+1; 132 path[step+1].y = j+1; 133 path[step+1].col = k; 134 dfs(tmp, step+1); 135 } 136 } 137 } 138 } 139 140 void solve() { 141 sol = -hinf; 142 M gra; 143 FF(i, r) 144 FF(j, c) 145 scanf("%d", &gra.d[i][j]); 146 for(deapth = 1; ; deapth++) { 147 FF(i, deapth+1) bvst[i].reset(); 148 dfs(gra, 0); 149 if(sol != -hinf) break; 150 } 151 } 152 153 int main(void) { 154 #ifndef ONLINE_JUDGE 155 freopen("in.txt", "r", stdin); 156 #endif 157 while(scanf("%d %d", &r, &c) == 2) { 158 solve(); 159 } 160 return 0; 161 }