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");
}
}
- poj1077
- poj1077
- POJ1077
- poj1077
- poj1077 Eight
- poj1077小议
- poj1077(A*,IDA*)
- POJ1077 八数码问题
- poj1077 /hdoj 1043 Eight
- poj1077解题报告详解
- 【POJ1077】Eight【IDA*】
- POJ1077——Eight
- POJ1077(8数码问题)
- Eight poj1077 广度优先搜索
- 启发式搜索及应用、POJ1077
- 八数码难题 hdu1043/ poj1077
- poj1077 hdu1043 Eight 八数码问题
- Poj1077/HDU1043(A*搜索)八数码问题
- 解析Axis客户端响应速度慢
- 建造者模式(Builder Pattern)
- 常见几种排序总结
- 第四周任务4(工资涨100元后排序)
- 经典小程序
- POJ1077
- 帮助你有效处理日期相关功能的Javascript类库 - XDate
- 经典小程序
- 帮助你自动生成浏览器特有CSS3属性的Javascript类库 - CSSFx
- 将论文中的所有参考文献编号批量上标化
- wxPython学习
- 经典小程序
- 图形学算法--Bresenham算法的改进(综合各个方向)
- 美萍2012 激活码 追码成功!