//疯狂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 }
posted on 2012-10-18 00:09  cchun  阅读(405)  评论(0编辑  收藏  举报