POJ1077

来源:互联网 发布:公司网络屏蔽了视频 编辑:程序博客网 时间:2024/06/05 05:38

昨天练习的题目,前天才学A*,昨天敲错了,保存的不是状态真不知道自己怎么想的。

这道题还有一个地方就是需要康拓展开,看了别人的解释才明白,后来发现这道题可以直接写BFS,害得我昨天一直在纠结A*。

今天将普通BFS写一下,然后再写了一下A*一个70ms,一个35ms也没快多少。自己写的A*有一个问题就是当需要存储的状态已经在OPEN里面了,但是如何更新.我直接省略了这一步。觉得将它们全部放入让优先队列自己找就好了。但是空间耗费也是不可想象的。贴上两份代码;

普通BFS:

#include<cstdio>
#include<cstring>
#include<stdlib.h>
using namespace std;
int f[10];
bool vis[4000000];
int q[500000][10];
int path[500000];
int change[500000];
int ans[500000];
void ini(){
int i=0;
f[0]=1;
for(i=1;i<=9;i++){
f[i]=f[i-1]*i;
}
}
int hash(int a[10]){
int res=0,i;
for(i=0;i<=8;i++){
res+=a[i]*f[i+1];
}
return res;
}
void copy(int a[10],int b[10]){
int i;
for(i=0;i<=8;i++){
b[i]=a[i];
}
}
main(){
char ch;
int i,b[10],flag=0,front=0,rear=1,j;
ini();
for(i=0;i<=8;i++){
scanf("%c",&ch);
getchar();
if(ch!='x')
b[i]=ch-'0';
else 
b[i]=9;
}
for(i=0;i<=8;i++){
for(j=0;j<i;j++){
if(b[i]>b[j] && b[i]!=9 && b[j]!=9)
flag++;
}
}
if(flag%2)
printf("unsolvable\n");
else{
memset(vis,0,sizeof(vis));
copy(b,q[0]);
path[0]=-1;
change[0]=0;
vis[hash(q[0])]=1;
//printf("wa\n");
while(front!=rear){
//printf("wa\n");
int cnt[10],pos,tmp;
copy(q[front],cnt);
if(hash(cnt)==3628799)
break;
for(i=0;i<=8;i++){
if(cnt[i]==9)
pos=i;
}
//printf("%d\n",pos);
if((pos-1)>=0 && (pos-1)/3==pos/3){

tmp=cnt[pos-1];
cnt[pos-1]=cnt[pos];
cnt[pos]=tmp;
if(!vis[hash(cnt)]){
//printf("wa\n");
copy(cnt,q[rear]);
path[rear]=front;
change[rear++]=-1;
vis[hash(cnt)]=1;
}
}
if((pos+1)<=8 && (pos+1)/3==pos/3){
copy(q[front],cnt);
tmp=cnt[pos+1];
cnt[pos+1]=cnt[pos];
cnt[pos]=tmp;
if(!vis[hash(cnt)]){
copy(cnt,q[rear]);
path[rear]=front;
change[rear++]=1;
vis[hash(cnt)]=1;
}
}
if((pos+3)<=8){
copy(q[front],cnt);
tmp=cnt[pos+3];
cnt[pos+3]=cnt[pos];
cnt[pos]=tmp;
if(!vis[hash(cnt)]){
copy(cnt,q[rear]);
path[rear]=front;
change[rear++]=3;
vis[hash(cnt)]=1;
}
}
if((pos-3)>=0){
copy(q[front],cnt);
tmp=cnt[pos-3];
cnt[pos-3]=cnt[pos];
cnt[pos]=tmp;
if(!vis[hash(cnt)]){
copy(cnt,q[rear]);
path[rear]=front;
change[rear++]=-3;
vis[hash(cnt)]=1;
}
}
front++;
}
int k=0;
for(i=front;path[i]!=-1;i=path[i]){
ans[k++]=change[i];
}
for(i=k-1;i>=0;i--){
if(ans[i]==-3)
printf("u");
if(ans[i]==3)
printf("d");
if(ans[i]==1)
printf("r");
if(ans[i]==-1)
printf("l");
}
printf("\n");
}
}

然后A*算法:

#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
bool visopen[4000000],visclose[4000000];
struct node{
int f,g,h,path,change;
int state[10];
friend bool operator < (node a, node b)
    {
        return a.f > b.f; //结构体中,x小的优先级高
    }
};
node open[4000000],close[4000000];
priority_queue<node>q;
int ans[1000000],f[100];
void ini(){
int i=0;
f[0]=1;
for(i=1;i<=9;i++){
f[i]=f[i-1]*i;
}
}
int hash(int a[10]){
int res=0,i;
for(i=0;i<=8;i++){
res+=a[i]*f[i+1];
}
return res;
}
void copy(int a[10],int b[10]){
int i;
for(i=0;i<=8;i++){
b[i]=a[i];
}
}
int eva(int a[10]){
int res=0,i;
for(i=0;i<=8;i++){
res+=fabs((a[i]-1)/3-i/3)+fabs((a[i]-1)%3-i%3);
}
return res;
}
int cnode(node a,int pos){
close[pos].f=a.f;
close[pos].g=a.g;
close[pos].h=a.h;
close[pos].path=a.path;
close[pos].change=a.change;
}
main(){
char ch;
int i,b[10],flag=0,j;
node cnt;
ini();
for(i=0;i<=8;i++){
scanf("%c",&ch);
getchar();
if(ch!='x')
b[i]=ch-'0';
else
b[i]=9;
}
for(i=0;i<=8;i++){
for(j=0;j<i;j++){
if(b[i]<b[j] && b[i]!=9 && b[j]!=9)
flag++;
}
}
if(flag%2)
printf("unsolvable\n");
else{
memset(visclose,0,sizeof(visclose));
copy(b,cnt.state);
while(!q.empty());
cnt.g=0;
cnt.h=eva(b);
cnt.f=cnt.h+cnt.g;
cnt.path=-1;
cnt.change=0;
q.push(cnt);
while(!q.empty()){
int c[10],tmp,pos;
node re;
cnt=q.top();
q.pop();
//printf("%d\n",cnt.f);
visclose[hash(cnt.state)]=1;
cnode(cnt,hash(cnt.state));
if(hash(cnt.state)==3628799){
break;
}
for(i=0;i<=8;i++){
if(cnt.state[i]==9)
pos=i;
}
if((pos-1)>=0 && (pos-1)/3==pos/3){
copy(cnt.state,c);
tmp=c[pos-1];
c[pos-1]=c[pos];
c[pos]=tmp;
copy(c,re.state);
re.g=cnt.g+1;
re.h=eva(re.state);
re.f=re.g+re.h;
re.path=hash(cnt.state);
re.change=-1;
if(!visclose[hash(re.state)]){
q.push(re);
//printf("in:%d\n",re.f);
//system("pause");
}
}
if((pos+1)<=8 && (pos+1)/3==pos/3){
copy(cnt.state,c);
tmp=c[pos+1];
c[pos+1]=c[pos];
c[pos]=tmp;
copy(c,re.state);
re.g=cnt.g+1;
re.h=eva(re.state);
re.f=re.g+re.h;
re.path=hash(cnt.state);
re.change=1;
if(!visclose[hash(re.state)]){
q.push(re);
//printf("in:%d\n",re.f);
//system("pause");
}
}
if((pos+3)<=8){
copy(cnt.state,c);
tmp=c[pos+3];
c[pos+3]=c[pos];
c[pos]=tmp;
copy(c,re.state);
re.g=cnt.g+1;
re.h=eva(re.state);
re.f=re.g+re.h;
re.path=hash(cnt.state);
re.change=3;
if(!visclose[hash(re.state)]){
q.push(re);
//printf("in:%d\n",re.f);
//system("pause");
}
}
if((pos-3)>=0){
copy(cnt.state,c);
tmp=c[pos-3];
c[pos-3]=c[pos];
c[pos]=tmp;
copy(c,re.state);
re.g=cnt.g+1;
re.h=eva(re.state);
re.f=re.g+re.h;
re.path=hash(cnt.state);
re.change=-3;
if(!visclose[hash(re.state)]){
q.push(re);
//printf("in:%d\n",re.f);
// system("pause");
}
}
}
int k=0;
for(i=3628799;i!=hash(b);i=close[i].path){
ans[k++]=close[i].change;
//printf("%d %d\n",close[i].change,close[i].path);
//system("pause");
//printf("wa\n");
}
// printf("%d\n",k);
//system("pause");
for(i=k-1;i>=0;i--){
if(ans[i]==-3)
printf("u");
if(ans[i]==3)
printf("d");
if(ans[i]==1)
printf("r");
if(ans[i]==-1)
printf("l");
}
printf("\n");
}
}

原创粉丝点击