题意:中文题,略。
题解:实际上原状态每个数在最后都对应着目标态相应位置,所以可以先通过不改变的移动达到相应位置,然后再增减数字得到目标态,这样bfs状态量就会一下降很多,6个数的排列也就6!,另外最后要求增减数字,所以光标必须到过那个地方,所以还需要一维记录光标到过的地方,由于光标移动受一定限制,所以最后只有10中光标访问位置的状态,即从6!排列中的一些光标状态中选出最优更改,事实证明,只有500多种状态。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=10000; 6 int sign[10][6]= 7 { 8 1,0,0,0,0,0, 9 1,1,0,0,0,0, 10 1,1,1,0,0,0, 11 1,1,1,1,0,0, 12 1,1,1,1,1,0, 13 1,1,1,1,1,1,//5 14 1,0,0,0,0,1, 15 1,1,0,0,0,1, 16 1,1,1,0,0,1, 17 1,1,1,1,0,1 18 };//光标移动域 19 int way[N][8],top;//排列与状态、步数 20 struct Data 21 { 22 int ar[6],step,state,pos;//数列,步数,光标状态 23 }; 24 bool mark[6][6][6][6][6][6][6][10];//bfs状态集 25 void bfs() 26 { 27 Data a,b,stk[N]; 28 int f,r; 29 f=r=top=0; 30 for(int i=0;i<6;i++) 31 a.ar[i]=i; 32 a.step=a.state=a.pos=0; 33 stk[r++]=a; 34 memset(mark,false,sizeof(mark)); 35 mark[a.ar[0]][a.ar[1]][a.ar[2]][a.ar[3]][a.ar[4]][a.ar[5]][a.pos][a.state]=true; 36 while(f!=r) 37 { 38 a=stk[f++]; 39 if(f==N) 40 f=0; 41 for(int i=0;i<6;i++) 42 way[top][i]=a.ar[i]; 43 way[top][6]=a.state; 44 way[top++][7]=a.step; 45 b=a; 46 b.step++; 47 if(b.pos>0) 48 { 49 swap(b.ar[0],b.ar[b.pos]); 50 if(!mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]) 51 { 52 mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]=true; 53 stk[r++]=b; 54 if(r==N) 55 r=0; 56 } 57 swap(b.ar[0],b.ar[b.pos]); 58 } 59 if(b.pos<5) 60 { 61 int temp=b.state; 62 b.pos++; 63 if(b.pos>b.state||(b.state>5&&b.pos>b.state-6)) 64 { 65 if(b.state == 9) b.state = 5; 66 else ++b.state; 67 } 68 if(!mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]) 69 { 70 mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]=true; 71 stk[r++]=b; 72 if(r==N) 73 r=0; 74 } 75 --b.pos; 76 b.state=temp; 77 swap(b.ar[5],b.ar[b.pos]); 78 if(b.state<5) 79 b.state+=6; 80 if(!mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]) 81 { 82 mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]=true; 83 stk[r++]=b; 84 if(r==N) 85 r=0; 86 } 87 } 88 } 89 } 90 int main() 91 { 92 bfs(); 93 int start,end; 94 while(scanf("%d%d",&start,&end)!=EOF) 95 { 96 int a[6],b[6]; 97 for(int i=5;i>=0;i--) 98 { 99 a[i]=start%10; 100 b[i]=end%10; 101 start/=10; 102 end/=10; 103 } 104 int ans=1<<29,st; 105 for(int i=0,j;i<top;i++) 106 { 107 st=way[i][7]; 108 for(j=0;j<6;j++) 109 { 110 if(a[way[i][j]]!=b[j]&&!sign[way[i][6]][j]) 111 break; 112 else 113 st+=abs(a[way[i][j]]-b[j]); 114 } 115 if(j==6&&st<ans) 116 ans=st; 117 } 118 printf("%d\n",ans); 119 } 120 return 0; 121 }