(建议先看前5大境界)
这里相比于上一境界,又增加了一个逆序数判无解的操作,因为第5个境界,双向bfs在无解的时候,显现出了比单向bfs更低的效率(因为他出了更多次的队列,相比于单向 bfs)。
什么是逆序数?
比如2 4 3 1。
依次看下去,2比1大,4比3大,4比1大,3比1大。所以逆序数就是4。
所以我们得知了逆序数就是体现在一个逆字上。相比于在正常序列下1234。有多少前面的数比后面的数大的这种情况,就是逆序数了。
逆序数为什么可以判无解?
因为如果起始状态和目标状态,如果把目标状态的x也放到右下角,如果起始状态逆序数的奇偶性和目标状态的奇偶性是一样的,那行就代表这两个状态可以互相移动到。反之,就不可以互相移动到。
(感兴趣的的人看看证明吧,不感兴趣直接用也行)
http://blog.csdn.net/qq_36523667/article/details/78798403
判断代码
- bool inverse(char ss[])
- {
- int t=0,x,y;
- for(int i=1;i<9;i++)
- for(int j=0;j<i;j++)
- {
- if(ss[j]=='x')continue;
- else x=ss[j]-'0';
- if(ss[i]=='x')continue;
- else y=ss[i]-'0';
- if(x>y)
- t++;
- }
- if(t&1)
- return true;
- return false;
- }
这个判断代码另外的步骤我就不是很懂了,不是应该遍历每一个数,在遍历的过程中,找剩下的数比他小的吗?
所以这里读者看不懂可以按照自己的思路来写。(此外我发现他的代码并没有把x归到右下角再进行逆序数的查找!这个应该是要的!)
全部代码(除了判断代码,都和上一章一样)
- #define N 512345
- char ss[10];
- struct node
- {
- char str[10];
- int mark,num;
- int index,hashnum;
- };
- struct res
- {
- int fa,now;
- }res1[N],res2[N];
- int vis1[N],vis2[N];
- int fac[] = {1,1,2,6,24,120,720,5040,40320};
- int over,ans1,ans2,sum1,sum2,cnt1,cnt2;
- int hehe[N];
- int KT(char ss[])
- {
- int i, j, t, sum;
- int s[10];
- for(i=0;i<9;i++)
- {
- if(ss[i]=='x')
- s[i]=0;
- else
- s[i]=ss[i]-'0';
- }
- sum = 0;
- for (i=0; i<9; i++)
- {
- t = 0;
- for (j=i+1; j<9; j++)
- if (s[j] < s[i])
- t++;
- sum += t*fac[9-i-1];
- }
- return sum+1;
- }
- bool bfs(char ss[], int temp)
- {
- char c;
- queue<node> q;
- while(!q.empty())q.pop();
- node g,h;
- for(int i=0;i<8;i++)
- g.str[i]=i+1+'0';
- g.str[8]='x';g.str[9]='\0';
- g.mark=0;g.num=0;g.index=8;
- vis1[KT(g.str)]=0;
- q.push(g);
- for(int i=0;i<9;i++)
- g.str[i]=ss[i];
- g.mark=1;g.num=0;g.index=temp;
- vis2[KT(g.str)]=0;
- q.push(g);
- sum1=sum2=1;
- cnt1=cnt2=1;
- while(!q.empty())
- {
- g=q.front();q.pop();
- int t = KT(g.str);
- if(g.mark==0)sum1--;
- else sum2--;
- if(g.mark==0&&vis2[t]!=-1)
- {
- ans1=g.num;
- ans2=vis2[t];
- return true;
- }
- if(g.mark==1&&vis1[t]!=-1)
- {
- ans2=g.num;
- ans1=vis1[t];
- return true;
- }
- h=g;
- if((h.index+1)%3!=0)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
- h.index++;
- if(!h.mark){res1[cnt1].now=4;res1[cnt1].fa=h.num;h.num=cnt1;cnt1++;}
- else {res2[cnt2].now=4;res2[cnt2].fa=h.num;h.num=cnt2;cnt2++;}
- int t=KT(h.str);
- if(vis1[t]==-1&&!h.mark)
- {
- vis1[t]=h.num;
- q.push(h);
- sum1++;
- }
- else if(vis2[t]==-1&&h.mark)
- {
- vis2[t]=h.num;
- q.push(h);
- sum2++;
- }
- }
- h=g;
- if(h.index%3!=0)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index-1];h.str[h.index-1]=c;
- h.index--;
- if(!h.mark){res1[cnt1].now=3;res1[cnt1].fa=h.num;h.num=cnt1;cnt1++;}
- else {res2[cnt2].now=3;res2[cnt2].fa=h.num;h.num=cnt2;cnt2++;}
- int t=KT(h.str);
- if(vis1[t]==-1&&!h.mark)
- {
- vis1[t]=h.num;
- q.push(h);
- sum1++;
- }
- else if(vis2[t]==-1&&h.mark)
- {
- vis2[t]=h.num;
- q.push(h);
- sum2++;
- }
- }
- h=g;
- if(h.index<6)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index+3];h.str[h.index+3]=c;
- h.index+=3;
- if(!h.mark){res1[cnt1].now=2;res1[cnt1].fa=h.num;h.num=cnt1;cnt1++;}
- else {res2[cnt2].now=2;res2[cnt2].fa=h.num;h.num=cnt2;cnt2++;}
- int t=KT(h.str);
- if(vis1[t]==-1&&!h.mark)
- {
- vis1[t]=h.num;
- q.push(h);
- sum1++;
- }
- else if(vis2[t]==-1&&h.mark)
- {
- vis2[t]=h.num;
- q.push(h);
- sum2++;
- }
- }
- h=g;
- if(h.index>2)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index-3];h.str[h.index-3]=c;
- h.index-=3;
- if(!h.mark){res1[cnt1].now=1;res1[cnt1].fa=h.num;h.num=cnt1;cnt1++;}
- else {res2[cnt2].now=1;res2[cnt2].fa=h.num;h.num=cnt2;cnt2++;}
- int t=KT(h.str);
- if(vis1[t]==-1&&!h.mark)
- {
- vis1[t]=h.num;
- q.push(h);
- sum1++;
- }
- else if(vis2[t]==-1&&h.mark)
- {
- vis2[t]=h.num;
- q.push(h);
- sum2++;
- }
- }
- if(sum1==0||sum2==0)
- return false;
- }
- return false;
- }
- bool inverse(char ss[])
- {
- int t=0,x,y;
- for(int i=1;i<9;i++)
- for(int j=0;j<i;j++)
- {
- if(ss[j]=='x')continue;
- else x=ss[j]-'0';
- if(ss[i]=='x')continue;
- else y=ss[i]-'0';
- if(x>y)
- t++;
- }
- if(t&1)
- return true;
- return false;
- }
- int main()
- {
- int i,j,k,kk,t,x,y,z;
- while(scanf("%s",ss)!=EOF)
- {
- if(ss[0]=='x')x=0;
- for(i=1;i<9;i++)
- {
- scanf("%s",ss+i);
- if(ss[i]=='x') x=i;
- }
- if(inverse(ss))
- {
- printf("unsolvable\n");
- continue;
- }
- ans1=ans2=-1;
- memset(vis1,-1,sizeof(vis1));
- memset(vis2,-1,sizeof(vis2));
- res1[0].now=res2[0].now=-1;
- if(bfs(ss,x))
- {
- x=0;
- if(res2[ans2].now==-1&&res1[ans1].now==-1)
- {
- printf("lr\n");
- continue;
- }
- while(res2[ans2].now!=-1)
- {
- hehe[x++]=res2[ans2].now;
- ans2=res2[ans2].fa;
- }
- for(i=x-1;i>=0;i--)
- {
- if(hehe[i]==1)printf("u");
- if(hehe[i]==2)printf("d");
- if(hehe[i]==3)printf("l");
- if(hehe[i]==4)printf("r");
- }
- while(res1[ans1].now!=-1)
- {
- if(res1[ans1].now==1)printf("d");
- if(res1[ans1].now==2)printf("u");
- if(res1[ans1].now==3)printf("r");
- if(res1[ans1].now==4)printf("l");
- ans1=res1[ans1].fa;
- }
- }
- else
- printf("unsolvable");
- printf("\n");
- }
- return 0;
- }