poj 1077/hdoj 1043
题目大意:你懂得
解决:A*,在poj上数据很弱,后来他们说zoj和hdoj都有这道题,就在过一下,这次数据是多组的,没想到都超时了,原因是
有无解的情况,关键是如何判断无解的情况,他们说提前都能判断出来,判了两次没盘出来,后来才知道是这样整的:由于一个空格和其他的数字交换位置,若是与同一行交换,逆序数的个数不变(这可是不包含9,就把那个当成空格处理),若是与同一列交换,要么是增加2,要么是减少2,可见奇偶性不变,根据这个可以判断出是否有解,若没有解在a*,因为一定会有解
顺便推荐一篇好文章 http://hi.baidu.com/benbearlove/blog/item/0c8b68db5ea9c3c8b6fd48a3.html
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define N 362885
#define in(x,y) (x>=0 && x< 3 && y>=0 && y<3)
int endpos[10][2];
int map[3][3];
int fact[]={1,1,2,6,24,120,720,5040,40320,362880};
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int sx,sy;
bool vis[N];
char d[]="durl";
char res[1000];
int p;
struct pos
{
int dir,pre;
pos(){}
pos(int d,int p):dir(d),pre(p){}
};
pos path[368225];
struct node
{
int map[3][3];
int id;
int x,y;
int fs;
int gs;
int hs;
node(int m[][3],int i,int xx,int yy,int g,int h):id(i),x(xx),y(yy),gs(g),hs(h){memcpy(map,m,sizeof(map)); fs=gs+hs;}
node(){}
};
bool operator < (const node &a,const node &b)
{//后来将比较函数改成了这个
if(a.fs!=b.fs)return a.fs>b.fs;
return a.gs>b.gs;
}
int hash(int map[][3])
{
int sum=0,cnt;
for(int i=0;i<9;i++)
{
cnt=0;
for(int j=i+1;j<9;j++)
if(map[j/3][j%3]<map[i/3][i%3])cnt++;
sum+=fact[8-i]*cnt;
}
return sum;
}
int heur(int m[][3])
{
int sum=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
sum+=abs(i-endpos[m[i][j]][0])+abs(j-endpos[m[i][j]][1]);
return sum;
}
int check(int map[][3])
{
int cnt=0;
for(int i=0;i<9;i++)
{
if(map[i/3][i%3]==9)continue;
for(int j=i+1;j<9;j++)
{
if(map[j/3][j%3]==9)continue;
if(map[j/3][j%3] < map[i/3][i%3])cnt++;
}
}
return cnt;
}
bool astar()
{
priority_queue<node> q;
node beg=node(map,hash(map),sx,sy,0,heur(map));
if(beg.id==0){path[0]=pos(0,-1);return 1;}
int t=check(map);
if(t%2)return 0;
vis[beg.id]=1;
path[beg.id]=pos(0,-1);
q.push(beg);
node now,next;
while(!q.empty())
{
now=q.top();
q.pop();
for(int i=0;i<4;i++)
{
next=now;
next.x=now.x+dx[i];
next.y=now.y+dy[i];
if(in(next.x,next.y))
{
swap(next.map[now.x][now.y],next.map[next.x][next.y]);
next.id=hash(next.map);
if(vis[next.id])continue;
vis[next.id]=1;
next.hs=heur(next.map);
next.gs++;
next.fs=next.hs+next.gs;
path[next.id]=pos(i,now.id);
if(next.id==0)return 1;
q.push(next);
}
}
}
}
void print(int t)
{
if(path[t].pre>=0)
{
print(path[t].pre);
res[p++]=d[path[t].dir];
}
}
int main()
{
int i,j,k=1;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
endpos[k][0]=i,endpos[k++][1]=j;
char ch[30];
while( gets(ch) )
{
memset(vis,0,sizeof(vis));
i=0,j=0;
while(ch[i])
{
if(ch[i]=='x'){sx=j/3; sy=j%3; map[sx][sy]=9; j++; }
else if(ch[i]>='0' && ch[i]<='9'){map[j/3][j%3]=ch[i]-'0';j++;}
i++;
}
if(astar())
{
p=0;
print(0);
res[p]='\0';
puts(res);
}
else puts("unsolvable");
}
system("pause");
return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#define N 362885
using namespace std;
bool visit[N];
int st,a[3][3],end;
int dir[9]={1,1,2,6,24,120,720,5040,40320};
int endpos[10][2]={0,0,0,0,0,1,0,2,1,0,1,1,1,2,2,0,2,1,2,2};
int sx,sy;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
char d[]="durl";
char res[100];
int p;
struct pos
{
char dir;
int pre;
pos(){}
pos(int d,int p):dir(d),pre(p){}
};
pos path[N];
struct node
{
int map[3][3];
int ans;
int x;
int y;
int f;
int g;
bool operator <(const node & a)const
{
return f>a.f;
}
};
int hash(int map[][3])
{
int cnt,sum=0;
for(int i=0;i<9;i++)
{
cnt=0;
for(int j=i+1;j<9;j++)
if(map[j/3][j%3] < map[i/3][i%3])cnt++;
sum+=dir[8-i]*cnt;
}
return sum;
}
int abs(int x){ return x<0?(-x):x; }
int h(int map[][3])
{
int sum=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
sum+=abs(i-endpos[map[i][j]][0])+abs(j-endpos[map[i][j]][1]);
return sum;
}
void bfs()
{
int ans;
priority_queue<node> q;
node cur,next;
memcpy(cur.map,a,sizeof(a));
cur.ans=st=hash(a);
path[cur.ans]=pos(0,-1);
visit[cur.ans]=1;
if(st==end)return;
cur.x=sx;
cur.y=sy;
cur.f=h(a);
cur.g=0;
q.push(cur);
while(!q.empty())
{
cur=q.top();
q.pop();
for(int i=0;i<4;i++)
{
next=cur;
next.x=cur.x+dx[i];
next.y=cur.y+dy[i];
if(next.x<0 || next.x>=3 || next.y <0 || next.y >=3)continue;
next.map[cur.x][cur.y]=next.map[next.x][next.y];
next.map[next.x][next.y]=9;
ans=hash(next.map);
if(visit[ans])continue;
visit[ans]=1;
next.g++;
next.f= next.g+h(next.map);
next.ans=ans;
path[next.ans]=pos(d[i],cur.ans);
if(ans==end)return;
q.push(next);
}
}
}
int check(int map[][3])
{
int cnt=0;
for(int i=0;i<9;i++)
{
if(map[i/3][i%3]==9)continue;
for(int j=i+1;j<9;j++)
{
if(map[j/3][j%3]==9)continue;
if(map[j/3][j%3] < map[i/3][i%3])cnt++;
}
}
return cnt;
}
void print(int t)
{
if(path[t].pre>=0)
{
print(path[t].pre);
res[p++]=path[t].dir;
}
}
int main()
{
int i,j,ans;
char str[50];
while( gets(str) )
{
memset(visit,0,sizeof(visit));
i=0,j=0;
while(str[i])
{
if(str[i]=='x'){sx=j/3; sy=j%3; a[sx][sy]=9; j++; }
else if(str[i]>='0' && str[i]<='9'){a[j/3][j%3]=str[i]-'0';j++;}
i++;
}
end=0;
ans=check(a);
if(ans%2){puts("unsolvable"); continue; }
bfs();
j=0;
p=0;
while(j>=0)
{
res[p++]=path[j].dir;
j=path[j].pre;
}
p--;
for(int i=p-1;i>=0;i--)printf("%c",res[i]);
printf("\n");
}
system("pause");
return 0;
}