算法学社
記錄難忘的征途
posts - 141,comments - 220,trackbacks - 0
题目描述:
   玩flood-it游戏, 一个8*8的带6种颜色的格子. 每次占领与已占领的联通块相邻的联通块, 问最少几次可以全部占领完. 第一次占领左上角.

算法分析:
   不知道是不是数据变弱了,还是服务器太快了. 最基本的IDA*就可以过. 估价函数设成最傻的都可以. 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int N = 8;
 6 typedef pair<int,int> pnt;
 7 int vis[N][N], num[N][N], n, tp;
 8 pnt Q[N*N];
 9 inline bool fit(int x,int y){
10     return x >= 0 && x < n && y >= 0 && y < n && !vis[x][y];
11 }
12 inline void bfs(int sx,int sy) {
13     int head = 0, tail = 1;
14     vis[sx][sy] = 1;
15     Q[0] = make_pair(sx, sy);
16     int c = num[sx][sy];
17     //cout<< "bfs: "<<endl;
18     //cout<< c << endl;
19     while(head < tail) {
20         pnt u = Q[head ++];
21         for(int i = 0; i < 4; i++){
22             int x = u.first + (i == 0) - (i == 1);
23             int y = u.second + (i == 2) - (i == 3);
24             if(fit(x,y) && num[x][y] == c){
25         //        cout<<"v: "<<x<<" "<<y<<" "<< num[x][y]<<endl;
26                 vis[x][y] = 1;
27                 Q[tail ++] = make_pair(x, y);
28             }}}
29 }
30 typedef unsigned long long ll;
31 inline ll hash(){
32     ll ans = 0;
33     for(int i = 0; i< n; i++)
34         for(int j = 0; j < n; j ++)
35             ans <<= 1, ans ^= vis[i][j];
36     return ans;
37 }
38 inline void rehash(ll t) {
39     for(int i = n-1; i>= 0; i--)
40         for(int j = n-1; j>=0 ;j--, t>>=1)
41             vis[i][j] = t&1;
42 }
43 inline int cal(){
44     int h[6] = {0};
45     for(int i = 0; i < n; i++)
46         for(int j = 0; j< n; j++) if(!vis[i][j])
47             h[num[i][j]] = 1;
48     int ans = 0;
49     for(int i = 0; i < 6; i++)
50         ans += h[i];
51     return ans;
52 }
53 int dfs(int lvl) {
54     //cout<<"lvl: "<<lvl<<endl;
55     if(lvl == tp) return cal() == 0;
56     if(cal()+ lvl > tp) return 0;
57     ll tmp = hash();
58     for(int c = 0; c < 6; c ++){
59         int flag = 0;
60         for(int i = 0; i < n; i++)
61             for(int j = 0; j< n; j++) if(vis[i][j]) {
62                 for(int p = 0; p < 4; p ++ ){
63                     int x = i + (p == 0) - (p == 1);
64                     int y = j + (p == 2) - (p == 3);
65                     if(fit(x,y) && num[x][y] == c){
66                         bfs(x,y);
67                         flag = 1;
68                     }
69             }}
70         if(!flag) continue;
71         if(dfs(lvl + 1)) return 1;
72         rehash(tmp);
73     }
74     return 0;
75 }
76 int main(){
77     while(scanf("%d",&n), n) {
78         for(int i = 0; i < n ; i ++)
79             for(int j = 0; j < n; j++)
80                 scanf("%d",&num[i][j]);
81         memset(vis, 0, sizeof(vis));
82         bfs(0,0);
83         ll tmp = hash();
84         for(tp=cal();;tp++) {
85 //            cout<<tp<<endl;
86             if(dfs(0)) break;
87             rehash(tmp);
88         }
89         printf("%d\n",tp);
90     }
91 }
92 
posted on 2012-08-15 20:56 西月弦 阅读(404) 评论(0)  编辑 收藏 引用 所属分类: 解题报告

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理