标签:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 x
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12 13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x r-> d-> r->
2 3 4 1 5 x 7 6 8
ullddrurdllurdruldr由于状态多,正向搜素超时,所以我们从目标状态开始反向搜索,预处理到达每个状态的走法;这里唯一不好表示的就是状态和走法,走法我们选择string类,而状态我们则用康拓展开,对于给出n个互不相同的字符的状态,康拓展开很实用。自此解决了。#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<bitset> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) typedef long long LL; const int maxn = 400000; const int mod = 1000000007; int fac[]={1,1,2,6,24,120,720,5040,40320,362880}; int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; struct node { int s[9]; int pos; int val; string path; }; int hash[maxn],num[9]; string path[maxn]; char index[5]="durl"; int Hash(int a[]) { int sum=0; REPF(i,1,8) { int num=0; for(int j=0;j<i;j++) if(a[j]>a[i]) num++; sum+=num*fac[i]; } return sum; } void BFS() { CLEAR(hash,0); node st,ed; REP(i,8) st.s[i]=i+1; st.s[8]=9; st.pos=8;st.val=Hash(st.s); st.path=""; queue<node>q; path[st.val]=""; q.push(st); while(!q.empty()) { st=q.front(); q.pop(); int x=st.pos/3; int y=st.pos%3; REP(i,4) { int xx=x+dr[i][0]; int yy=y+dr[i][1]; if(xx>=0&&xx<=2&yy>=0&&yy<=2) { ed=st; ed.pos=xx*3+yy; ed.s[st.pos]=ed.s[ed.pos]; ed.s[ed.pos]=9; ed.val=Hash(ed.s); if(!hash[ed.val]) { hash[ed.val]=1; ed.path=index[i]+ed.path; q.push(ed); path[ed.val]=ed.path; } } } } } int main() { char str[110]; BFS(); while(gets(str)) { int len=strlen(str); int l=0; REP(i,len) { if(str[i]>='0'&&str[i]<='9') num[l++]=str[i]-'0'; else if(str[i]=='x') num[l++]=9; } if(hash[Hash(num)]) cout<<path[Hash(num)]<<endl; else cout<<"unsolvable"<<endl; } return 0; }
标签:
原文地址:http://blog.csdn.net/u013582254/article/details/42134375