POJ 1077 Eight BFS -
2016-09-12 12:36
369 查看
题目地址:http://poj.org/problem?id=1077
木有A*快..
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
struct Node{
int status;
int parent;
int move;
Node(int s=0,int p=0,int m=-1):status(s),parent(p),move(m){}
};
int toInt(int *A)
{
int x=0;
for(int i=0;i<9;i++)
x=x*10+A[i];
return x;
}
int toIntArray(int A[],int s)
{
int p;
for(int i=8;i>=0;i--)
{
A[i]=s%10;
if(!A[i]) p=i;
s/=10;
}
return p;
}
int h(int status)
{
int cnt=0;
int a[9];
toIntArray(a,status);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
int n=a[i*3+j]-1;
int x=n/3,y=n%3;
if(n==-1) x=y=2;
cnt+=abs(x-i)+abs(y-j);
}
return cnt;
}
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
bool inside(int x,int y){
return x>=0&&x<3&&y>=0&&y<3;
}
int move(int s,int i)
{
int b[9];
int p=toIntArray(b,s);
int x=p/3,y=p%3;
int nx=x+dx[i],ny=y+dy[i];;
if(!inside(nx,ny)) return -1;
int np=nx*3+ny;
swap(b[np],b[p]);
int ns=toInt(b);
return ns;
}
int fac[]={1,1,2,6,24,120,720,5040,40320};
bool vis[400000];
int rank(int s)
{
int a[9]; toIntArray(a,s);
int res=0,k;
for(int i=0;i<9;i++)
{
k=0;
for(int j=i+1;j<9;j++)
if(a[i]>a[j]) k++;
res+=k*fac[9-1-i];
}
return res;
}
Node Q[1000000+10];
int BFS(int s,int t)
{
int front=1,rear=0;
Q[0]=Node(s,-1,0);
vis[rank(s)]=true;
while(front>rear)
{
Node u=Q[rear];
int s=u.status;
if(s==t) return rear;
for(int i=0;i<4;i++)
{
int ns=move(s,i),r=rank(ns);
if(ns==-1||vis[r]) continue;
vis[r]=true;
Q[front++]=Node(ns,rear,i); //不用检查是否在open表里,因为f大的出不来
}
rear++;
}
return 0;
}
bool bSolved(int s){ //根据奇偶性,预判是否可以解决
int cnt=0,a[9];
toIntArray(a,s);
for(int i=0;i<9;i++)
{
if(!a[i]) continue;
for(int j=i+1;j<9;j++)
{
if(!a[j]) continue;
if(a[i]>a[j]) cnt++;
}
}
return cnt&1;
}
int main()
{
int a[10];char ch;
for(int i=0;i<9;i++) {
cin>>ch;
if(isdigit(ch)) a[i]=ch-'0';
else a[i]=0;
}
int s=toInt(a),t=123456780;
if(bSolved(s)){
cout<<"unsolvable"; return 0;
}
int m=BFS(s,t);
char d[5]="udlr";
string ans;
for(Node i=Q[m];i.parent!=-1;i=Q[i.parent])
ans+=d[i.move];
reverse(ans.begin(),ans.end());
cout<<ans<<endl;
return 0;
}
木有A*快..
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
struct Node{
int status;
int parent;
int move;
Node(int s=0,int p=0,int m=-1):status(s),parent(p),move(m){}
};
int toInt(int *A)
{
int x=0;
for(int i=0;i<9;i++)
x=x*10+A[i];
return x;
}
int toIntArray(int A[],int s)
{
int p;
for(int i=8;i>=0;i--)
{
A[i]=s%10;
if(!A[i]) p=i;
s/=10;
}
return p;
}
int h(int status)
{
int cnt=0;
int a[9];
toIntArray(a,status);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
int n=a[i*3+j]-1;
int x=n/3,y=n%3;
if(n==-1) x=y=2;
cnt+=abs(x-i)+abs(y-j);
}
return cnt;
}
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
bool inside(int x,int y){
return x>=0&&x<3&&y>=0&&y<3;
}
int move(int s,int i)
{
int b[9];
int p=toIntArray(b,s);
int x=p/3,y=p%3;
int nx=x+dx[i],ny=y+dy[i];;
if(!inside(nx,ny)) return -1;
int np=nx*3+ny;
swap(b[np],b[p]);
int ns=toInt(b);
return ns;
}
int fac[]={1,1,2,6,24,120,720,5040,40320};
bool vis[400000];
int rank(int s)
{
int a[9]; toIntArray(a,s);
int res=0,k;
for(int i=0;i<9;i++)
{
k=0;
for(int j=i+1;j<9;j++)
if(a[i]>a[j]) k++;
res+=k*fac[9-1-i];
}
return res;
}
Node Q[1000000+10];
int BFS(int s,int t)
{
int front=1,rear=0;
Q[0]=Node(s,-1,0);
vis[rank(s)]=true;
while(front>rear)
{
Node u=Q[rear];
int s=u.status;
if(s==t) return rear;
for(int i=0;i<4;i++)
{
int ns=move(s,i),r=rank(ns);
if(ns==-1||vis[r]) continue;
vis[r]=true;
Q[front++]=Node(ns,rear,i); //不用检查是否在open表里,因为f大的出不来
}
rear++;
}
return 0;
}
bool bSolved(int s){ //根据奇偶性,预判是否可以解决
int cnt=0,a[9];
toIntArray(a,s);
for(int i=0;i<9;i++)
{
if(!a[i]) continue;
for(int j=i+1;j<9;j++)
{
if(!a[j]) continue;
if(a[i]>a[j]) cnt++;
}
}
return cnt&1;
}
int main()
{
int a[10];char ch;
for(int i=0;i<9;i++) {
cin>>ch;
if(isdigit(ch)) a[i]=ch-'0';
else a[i]=0;
}
int s=toInt(a),t=123456780;
if(bSolved(s)){
cout<<"unsolvable"; return 0;
}
int m=BFS(s,t);
char d[5]="udlr";
string ans;
for(Node i=Q[m];i.parent!=-1;i=Q[i.parent])
ans+=d[i.move];
reverse(ans.begin(),ans.end());
cout<<ans<<endl;
return 0;
}
相关文章推荐
- 搜索 ( 八数码问题详解:BFS,A*,IDA* )——Eight ( POJ 1077 )
- HDU 1043 && POJ 1077 Eight bfs || 双向bfs || A*搜索
- HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)
- HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)
- poj 1077 Eight(经典八数码问题:bfs/Dbfs)
- POJ 1077 Eight & HDU 1043 Eight(康托展开+BFS)
- BFS(八数码) POJ 1077 || HDOJ 1043 Eight
- POJ 1077 Eight 八数码问题 BFS
- poj 1077-Eight(八数码+逆向bfs打表)
- hdu 1043 eight(poj 1077) (bfs)
- poj 1077--Eight(八数码问题,BFS,A*,全排列的哈希)
- POJ 1077 Eight(BFS:输出路径)
- poj 1077 Eight 八数码问题( 康拓展开+BFS状态压缩)
- poj 1077 & hdu 1043 Eight ( 多种解法:预处理、bfs、dbfs、IDA*、A*)
- POJ 1077 Eight(bfs八数码问题)
- POJ 1077 Eight(BFS Hash)
- poj 1077 Eight (bfs A* IDA*)
- POJ 1077 Eight(BFS八数码问题)
- POJ - 1077 Eight : 八数码 -- 哈唏 康托展开 双向bfs A* IDA*
- POJ 1077 Eight(康拓展开 BFS 双向BFS)