poj 1077(八数码)

本文介绍了一种解决八数码问题的方法——双向搜索算法。通过使用C++实现,该算法能够高效地找到从任意初始状态到目标状态的路径。具体实现包括了节点结构定义、哈希函数、广度优先搜索等关键技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

八数码问题有多种解法,本题解采用的是双向搜索

View Code
  1 #include<iostream>
  2 #include<map>
  3 #include<string>
  4 #include<queue>
  5 #include<stdio.h>
  6 #include<string.h>
  7 using namespace std;
  8 structnode{
  9  stringsx;
 10  int pos;
 11 };
 12 
 13 int dir[4]={-3,1,3,-1};
 14 char ch1[4]={'u','r','d','l'};
 15 char ch2[4]={'d','l','u','r'};
 16 int fact[9]={1,1,2,6,24,120,720,5040,40320};
 17 int b[500050]={0};
 18 stringsstr[500050];
 19 int hash(stringstr)
 20 {
 21     int sum=0;
 22     for(int i=1;str[i];i++)
 23     {
 24         int cnt=0;
 25         for(int j=0;j<i;j++)
 26         if(str[i]<str[j])cnt++;
 27         sum+=cnt*fact[i];
 28     }
 29     return sum;
 30 }
 31 stringbfs(stringstr)
 32 {
 33     memset(b,0,sizeof(b));
 34     queue<node>q1,q2;
 35     nodein;
 36     in.sx=str;
 37     for(int i=0;str[i];i++){if(str[i]=='9')in.pos=i;}
 38     q1.push(in);
 39     b[hash(str)]=1;
 40     in.sx="123456789";
 41     in.pos=8;
 42     q2.push(in);
 43     b[hash(in.sx)]=2;
 44     while(!q1.empty()&&!q2.empty())
 45     {
 46         nodeu=q1.front();
 47         q1.pop();
 48         int f=hash(u.sx);
 49         for(int i=0;i<4;i++)
 50         {
 51             nodev;
 52             v.pos=u.pos+dir[i];
 53             if((u.pos<3&&i==0)||(u.pos%3>1&&i==1)||
 54                (u.pos/3>1&&i==2)||(u.pos%3<1&&i==3))
 55             continue;
 56             v.sx=u.sx;
 57             v.sx[v.pos]=u.sx[u.pos];
 58             v.sx[u.pos]=u.sx[v.pos];
 59             int t=hash(v.sx);
 60             if(b[t]==1)continue;
 61             else if(b[t]==2)return sstr[f]+ch1[i]+sstr[t];
 62             sstr[t]=sstr[f]+ch1[i];
 63             b[t]=1;
 64             q1.push(v);
 65         }
 66         u=q2.front();
 67         q2.pop();
 68         f=hash(u.sx);
 69         for(int i=0;i<4;i++)
 70         {
 71             nodev;
 72             v.pos=u.pos+dir[i];
 73             if((u.pos<3&&i==0)||(u.pos%3>1&&i==1)||
 74                (u.pos/3>1&&i==2)||(u.pos%3<1&&i==3))
 75             continue;
 76             v.sx=u.sx;
 77             v.sx[v.pos]=u.sx[u.pos];
 78             v.sx[u.pos]=u.sx[v.pos];
 79             int t=hash(v.sx);
 80             if(b[t]==2)continue;
 81             else if(b[t]==1)return sstr[t]+ch2[i]+sstr[f];
 82             sstr[t]=ch2[i]+sstr[f];
 83             b[t]=2;
 84             q2.push(v);
 85         }
 86     }
 87     return "unslovable";
 88 }
 89 int main()
 90 {
 91     memset(b,0,sizeof(b));
 92     char s[110];
 93     while(gets(s))
 94     {
 95         stringstr="";
 96         for(int i=0;s[i];i++)
 97         {
 98             if(s[i]>='0'&&s[i]<='9')str=str+s[i];
 99             else if(s[i]=='x')str=str+'9';
100         }
101         int i=0;
102         cout<<bfs(str)<<endl;
103     }
104     return 0;
105 }

 

转载于:https://www.cnblogs.com/huangriq/archive/2012/04/14/2446941.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值