做题感悟:
第一次做这题时用的是单向广搜,用的最笨的方法,把所有情况都列出来了。这一星期搞了一下双向广搜,百度了一下这题可以用双向广搜,正好借这题学一下双向广搜,学完才发现原来双向广搜广搜这么简单。
题意:
给你两个四位数的整数,让你从第一个经过若干次变化变成第二个。可以进行的操作:某一位减一(如果是 1,则变成 9 ),某一位加一(如果是 9 ,则变成 1 ),还可以交换相邻两位(第一位与第四位不相邻)。
解题思路:
每一位都进行:加一,减一,交换的操作(和暴力差不多)。
代码(双广):
#include<stdio.h> #include<queue> #include<string.h> using namespace std ; char s1[8],s2[8] ; int vis1[15][15][15][15],vis2[15][15][15][15] ; struct zhang { int x[8],step ; } ; int bbfs() { queue<zhang>q1,q2 ; zhang curt,next ; memset(vis1,-1,sizeof(vis1)) ; memset(vis2,-1,sizeof(vis2)) ; curt.step=0 ; next.step=0 ; for(int i=0 ;i<4 ;i++) { curt.x[i]=s1[i]-'0' ; next.x[i]=s2[i]-'0' ; } vis1[curt.x[0]][curt.x[1]][curt.x[2]][curt.x[3]]=0 ; vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]]=0 ; q1.push(curt) ; q2.push(next) ; int temp1=0,temp2=0,k ; while(1) { while(!q1.empty()&&temp1==q1.front().step) { curt=q1.front() ; q1.pop() ; if((k=vis2[curt.x[0]][curt.x[1]][curt.x[2]][curt.x[3]])!=-1) { return curt.step+k ; } curt.step=curt.step+1 ; for(int i=0 ;i<4 ;i++) // 加一和减一 { next=curt ; if(curt.x[i]==9) next.x[i]=1 ; else next.x[i]=curt.x[i]+1 ; if((k=vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]])!=-1) return next.step+k ; if(vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]]==-1) { vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]]=next.step ; q1.push(next) ; } if(curt.x[i]==1) next.x[i]=9 ; else next.x[i]=curt.x[i]-1 ; if((k=vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]])!=-1) return next.step+k ; if(vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]]==-1) { vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]]=next.step ; q1.push(next) ; } } for(int i=0 ;i<3 ;i++) // 相邻的交换 { next=curt ; next.x[i]=curt.x[i+1] ; next.x[i+1]=curt.x[i] ; if((k=vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]])!=-1) return next.step+k ; if(vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]]==-1) { vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]]=next.step ; q1.push(next) ; } } } temp1=q1.front().step ; while(!q2.empty()&&temp2==q2.front().step) // 反向搜索 { curt=q2.front() ; q2.pop() ; if((k=vis1[curt.x[0]][curt.x[1]][curt.x[2]][curt.x[3]])!=-1) { return curt.step+k ; } curt.step=curt.step+1 ; for(int i=0 ;i<4 ;i++) // 加一和减一 { next=curt ; if(curt.x[i]==9) // 加一 next.x[i]=1 ; else next.x[i]=curt.x[i]+1 ; if((k=vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]])!=-1) return next.step+k ; if(vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]]==-1) { vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]]=next.step ; q2.push(next) ; } if(curt.x[i]==1) // 减一 next.x[i]=9 ; else next.x[i]=curt.x[i]-1 ; if((k=vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]])!=-1) return next.step+k ; if(vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]]==-1) { vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]]=next.step ; q2.push(next) ; } } for(int i=0 ;i<3 ;i++) // 相邻的交换 { next=curt ; next.x[i]=curt.x[i+1] ; next.x[i+1]=curt.x[i] ; if((k=vis1[next.x[0]][next.x[1]][next.x[2]][next.x[3]])!=-1) return next.step+k ; if(vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]]==-1) { vis2[next.x[0]][next.x[1]][next.x[2]][next.x[3]]=next.step ; q2.push(next) ; } } } temp2=q2.front().step ; } } int main() { int T ; scanf("%d",&T) ; while(T--) { scanf("%s%s",s1,s2) ; printf("%d\n",bbfs()) ; } return 0 ; }