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; }