HDU 1043 八数码问题【双向BFS】
题目链接
题意:给你一个初始状态,问你能否移动到最终的完成状态,如果能输出任意一组解,否则输出unsolved。
思路:乍一看是个BFS,但是状态过多会TLE或者MLE,但是除可BFS确实没得写了,这时候就要用到双向BFS了,起点终点同时BFS,判断相遇,路径用string+就行了。
注意点:正向路径s=s+c,逆向s=c+s;输出也要注意先输出正向;
剪枝的话就判断逆序数就行了;
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<queue>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
char s[125];
map<int,string>vis1,vis2;
map<int,char>mp;
map<int,char>mpp;
int st=0,ed=123456780,dx,dy,mat[4][4],ans=-1,flag;
int dir[4][2]= {
{
0,1},{
0,-1},{
-1,0},{
1,0}};
struct node
{
int now;
string s;
};
void fun(int ok)
{
mat[1][1]=0;
dx=1,dy=1;
int j=3,i=3;
while(ok)
{
mat[i][j]=ok%10;
ok/=10;
if(!mat[i][j])
dx=i,dy=j;
j--;
if(j==0)
i--,j=3;
}
}
int tran()
{
int ans=0;
for(int i=1; i<=3; i++)
{
for(int j=1; j<=3; j++)
ans=ans*10+mat[i][j];
}
return ans;
}
int Tbfs()
{
mp[0]='r',mp[1]='l',mp[2]='u',mp[3]='d';
mpp[0]='l',mpp[1]='r',mpp[2]='d',mpp[3]='u';
queue<node>q1,q2;
node f;
q1.push({
st,""}),q2.push({
ed,""});
vis1[st]=1,vis2[ed]=1;
while(!q1.empty()&&!q2.empty())
{
if(q1.size()<q2.size())
f=q1.front(),q1.pop(),flag=1;
else
f=q2.front(),q2.pop(),flag=0;
fun(f.now);
for(int i=0; i<4; i++)
{
char c=mp[i];
char cc=mpp[i];
int xx=dir[i][0]+dx;
int yy=dir[i][1]+dy;
if(xx<1||xx>3||yy<1||yy>3)
continue;
swap(mat[xx][yy],mat[dx][dy]);
int no=tran();
swap(mat[xx][yy],mat[dx][dy]);
if(flag==1)///q1
{
if(vis1[no].size())
continue;
if(vis2[no].size())
{
cout<<f.s;
cout<<c;
cout<<vis2[no]<<endl;
return 1;
}
vis1[no]=f.s+c;
q1.push({
no,f.s+c});
}
else
{
if(vis2[no].size())
continue;
if(vis1[no].size())
{
cout<<vis1[no];
cout<<cc;
cout<<f.s<<endl;
return 1;
}
vis2[no]=cc+f.s;
q2.push({
no,cc+f.s});
}
}
}
return -1;
}
int main()
{
char c;
while(gets(s))
{
st=0;
ed=123456780;
vis1.clear(),vis2.clear();
int len=strlen(s);
int a[10],cnt=0;
for(int i=0; i<len; i++)
{
char c=s[i];
if(c==' ')continue;
else if(c=='x')
st=st*10;
else
{
st=st*10+(c-'0');
a[++cnt]=c-'0';
}
}
int k=0;
for(int i=1; i<=8; i++)
{
for(int j=i+1; j<=8; j++)
{
if(a[i]>a[j])
k++;
}
}
if(k&1)
{
printf("unsolvable\n");
continue;
}
ans=Tbfs();
if(ans==-1)
printf("unsolvable\n");
}
}