码迷,mamicode.com
首页 > 其他好文 > 详细

八数码三种用时差距极大的写法

时间:2017-04-27 23:08:04      阅读:328      评论:0      收藏:0      [点我收藏+]

标签:dba   algorithm   eof   i++   cst   isp   vector   解法   双向   

  进化史,一种比一种长,一种比一种快。不过第三种似乎还不是最终形态。

  第一种,傻逼级迭代加深。

  去年十一月写的,那时候刚刚学迭代加深,敲了一个钟头才敲完,codevs上直接过,就没太管,觉得这是个水题。实际上呢,看后文。

技术分享
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 int sx,sy,lim,a[4][4],t[4][4]={{},{0,1,2,3},{0,8,0,4},{0,7,6,5}},ax[]={-1,1,0,0},ay[]={0,0,-1,1};
 7 int f(){
 8     int cnt=0;
 9     for(int i=1;i<=3;i++)
10         for(int j=1;j<=3;j++)
11             cnt+=a[i][j]!=t[i][j];
12     return cnt;
13 }
14 void dfs(int x,int y,int s){
15     if(memcmp(a,t,sizeof(a))==0){cout<<s<<endl;exit(0);}
16     if(s+f()>lim)return;
17     for(int k=0;k<4;k++){
18         int nx=x+ax[k],ny=y+ay[k];
19         if(nx<1||ny<1||nx>3||ny>3)continue;
20         swap(a[nx][ny],a[x][y]);
21         dfs(nx,ny,s+1);
22         swap(a[nx][ny],a[x][y]);
23     }
24 }
25 int main(){
26     for(int i=1;i<=3;i++)
27         for(int j=1;j<=3;j++)
28             if((a[i][j]=getchar()-0)==0)sx=i,sy=j;
29     for(lim=1;lim<=100;lim++)dfs(sx,sy,0);
30     return 0;
31 }
View Code

  这种在洛谷上八十分,加上超时的第八和第十两个点,总用时2422。

 

  第二种,基础的单向广搜。

  前几天才听说原来八数码有多种解法,而且codevs上的数据极弱无比。我不信邪地把去年在codevs已经AC的代码提交在洛谷上,结果已经提到了。于是我决定花几天重打一遍,迭代加深再优化下去我一时还想不大出来,所以就先弄了下面这个单向广搜。

技术分享
 1 #include<map>
 2 #include<set>
 3 #include<queue>
 4 #include<cmath>
 5 #include<cstdio>
 6 #include<vector>
 7 #include<string>
 8 #include<cstring>
 9 #include<iostream>
10 #include<algorithm>
11 using namespace std;
12 const int ax[]={0,3,-1,1,-3};
13 const bool av[8][16]={{},{1,1,1,1,1,1,0,0,0},{0,1,1,0,1,1,0,1,1},
14     {1,1,0,1,1,0,1,1,0},{0,0,0,1,1,1,1,1,1}};
15 
16 struct bd{
17     string s;
18     int sp,pth;
19 }st;
20 queue<bd> q;
21 map<string,bool> tb;
22 bool dn;
23 int main(){
24     bd tg;
25     tg.s="123804765";
26     cin>>st.s;
27     for(int i=0;i<st.s.size();i++)if(st.s[i]==0){st.sp=i;break;}
28     st.pth=0;
29     tb[st.s]=true;
30     q.push(st);
31     while(!dn&&!q.empty()){
32         bd x=q.front();q.pop();
33         if(x.s==tg.s){
34             cout<<x.pth<<endl;
35             return 0;
36         }
37         for(int i=1;i<=4;i++){
38             if(!av[i][x.sp])continue;
39             bd nx=x;nx.sp+=ax[i];nx.pth=x.pth+1;
40             swap(nx.s[nx.sp],nx.s[x.sp]);
41             
42             if(!tb[nx.s]){
43                 q.push(nx);
44                 tb[nx.s]=true;
45             }
46         }
47     }
48     
49     return 0;
50 }
View Code

  此代码在洛谷上总用时2165。

 

  第三种,稍加改良的双向广搜

  我目前也只想打到这个程度了,上面那个单向是前天敲的,这个第三种半小时前才正式完工。用时比我预想的“理论上比单向减少一半”更惊喜。

技术分享
 1 #include<map>
 2 #include<set>
 3 #include<queue>
 4 #include<cmath>
 5 #include<cstdio>
 6 #include<vector>
 7 #include<string>
 8 #include<cstring>
 9 #include<iostream>
10 #include<algorithm>
11 using namespace std;
12 const int ax[]={0,3,-1,1,-3};
13 const bool av[8][16]={{},{1,1,1,1,1,1,0,0,0},{0,1,1,0,1,1,0,1,1},{1,1,0,1,1,0,1,1,0},{0,0,0,1,1,1,1,1,1}};
14 struct bd{
15     string s;
16     int sp,pth;
17 }st;
18 queue<bd> q1,q2;
19 map<string,int> tb1,tb2;
20 int main(){
21     bd tg;
22     tg.s="123804765";tg.sp=4;tg.pth=1;
23     tb2[tg.s]=1;
24     q2.push(tg);
25     cin>>st.s;
26     for(int i=0;i<st.s.size();i++)if(st.s[i]==0){st.sp=i;break;}
27     st.pth=1;
28     tb1[st.s]=1;
29     q1.push(st);
30     while(!q2.empty()&&!q1.empty()){
31         bd x1=q1.front(),x2=q2.front();q1.pop();q2.pop();
32         if(tb2[x1.s]){
33             cout<<x1.pth+tb2[x1.s]-2<<endl;
34             return 0;
35         }
36         if(tb1[x2.s]){
37             cout<<x2.pth+tb1[x2.s]-2<<endl;
38             return 0;
39         }
40         for(int i=1;i<=4;i++){
41             if(av[i][x1.sp]){
42                 bd nx=x1;
43                 nx.sp+=ax[i];nx.pth=x1.pth+1;
44                 swap(nx.s[nx.sp],nx.s[x1.sp]);
45                 if(!tb1[nx.s]){
46                     q1.push(nx);
47                     tb1[nx.s]=nx.pth;
48                 }
49             }
50             if(av[i][x2.sp]){
51                 bd nx=x2;
52                 nx.sp+=ax[i];nx.pth=x2.pth+1;
53                 swap(nx.s[nx.sp],nx.s[x2.sp]);
54                 if(!tb2[nx.s]){
55                     q2.push(nx);
56                     tb2[nx.s]=nx.pth;
57                 }
58             }
59         }
60     }
61     return 0;
62 }
View Code

  洛谷上总用时38。

 

八数码三种用时差距极大的写法

标签:dba   algorithm   eof   i++   cst   isp   vector   解法   双向   

原文地址:http://www.cnblogs.com/duskfire/p/6777320.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!