您的位置:首页 > 其它

hdu 1067(hash+bfs)

2014-05-26 17:58 429 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1067

思路:学会了手写Hash。。。orz....纪念一下。





1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<queue>
6 using namespace std;
7 #define MAXN 1000007
8 typedef long long ll;
9 ll Hash[MAXN];
10
11 struct Node{
12     int map[4][8],step;
13     bool operator == (const Node &p) const {
14         for(int i=0;i<4;i++)
15             for(int j=0;j<8;j++)
16                 if(map[i][j]!=p.map[i][j])
17                     return false;
18         return true;
19     }
20     //手写hash
21     ll HashValue(){
22         ll value=0;
23         for(int i=0;i<4;i++)
24             for(int j=0;j<8;j++)
25                 value+=(value<<ll(1))+(ll)map[i][j];
26         return value;
27     }
28 };
29
30 Node Start,End;
31
32 void Initaite(){
33     memset(Hash,-1,sizeof(Hash));
34     for(int i=0;i<4;i++){
35         Start.map[i][0]=0;
36         for(int j=1;j<8;j++){
37             scanf("%d",&Start.map[i][j]);
38         }
39     }
40     Start.step=0;
41 }
42
43 //最后的结果
44 void GetEnd(){
45     for(int i=0;i<4;i++){
46         End.map[i][7]=0;
47         for(int j=0;j<7;j++){
48             End.map[i][j]=(i+1)*10+(j+1);
49         }
50     }
51 }
52
53 //取得value的hash值+hash判重
54 bool HashInsert(ll value){
55     int v=value%MAXN;
56     while(Hash[v]!=-1&&Hash[v]!=value){
57         v+=10;
58         v%=MAXN;
59     }
60     if(Hash[v]==-1){
61         Hash[v]=value;
62         return true;
63     }
64     return false;
65 }
66
67 void bfs(){
68     queue<Node>Q;
69     Node p,q;
70     Q.push(Start);
71     HashInsert(Start.HashValue());
72     while(!Q.empty()){
73         p=Q.front();
74         Q.pop();
75         for(int i=0;i<4;i++){
76             for(int j=0;j<8;j++){
77                 if(!p.map[i][j]){
78                     q=p;
79                     q.step++;
80                     int value=p.map[i][j-1]+1;//找比map[i][j-1]大1的数
81                     if(value==1||value%10==8)continue;//0或者value为7的不能移动
82                     int x,y,flag=true;
83                     for(int k=0;k<4&&flag;k++){
84                         for(int l=1;l<8&&flag;l++){
85                             if(p.map[k][l]==value){
86                                 x=k,y=l;
87                                 flag=false;
88                             }
89                         }
90                     }
91                     if(!flag){
92                         swap(q.map[i][j],q.map[x][y]);
93                         ll value=q.HashValue();
94                         //hash判重
95                         if(HashInsert(value)){
96                             if(q==End){
97                                 printf("%d\n",q.step);
98                                 return ;
99                             }
100                             Q.push(q);
101                         }
102                     }
103                 }
104             }
105         }
106     }
107     puts("-1");
108 }
109
110 void Solve(){
111     int k=0;
112     //将11,21,31,41这四个数移到第0列
113     for(int i=0;i<4;i++){
114         for(int j=1;j<8;j++){
115             if(Start.map[i][j]==(k+1)*10+1){
116                 swap(Start.map[i][j],Start.map[k][0]);
117                 k++,i=0,j=0;
118             }
119         }
120     }
121     if(Start==End){
122         puts("0");//前四步不记录总步数
123         return ;
124     }
125     bfs();
126 }
127
128 int main(){
129     int _case;
130     scanf("%d",&_case);
131     GetEnd();
132     while(_case--){
133         Initaite();
134         Solve();
135     }
136     return 0;
137 }


View Code
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: