loj 1165(bfs+康托展开)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26879
思路:题目意思很简单,就是通过一些位置的交换,最后变成有序数列,对于一组序列,我们可以用康托展开然后hash判重。
然后就是普通的bfs,稍微留意一下细节即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 int is_prime[]={0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1}; 8 int fac[]={1,1,2,6,24,120,720,5040,40320}; 9 10 struct Point{ 11 int num,flag; 12 }; 13 14 struct Node{ 15 Point state[10]; 16 int step; 17 }st; 18 19 bool mark[400000]; 20 21 int Get_Hash(Node &node) 22 { 23 int a[10],val=0,cnt; 24 for(int i=0;i<8;i++)a[i]=abs(node.state[i].num); 25 for(int i=0;i<8;i++){ 26 cnt=0; 27 for(int j=0;j<i;j++){ 28 if(a[j]>a[i])cnt++; 29 } 30 val+=cnt*fac[i]; 31 } 32 return val; 33 } 34 35 bool Judge(Node &node) 36 { 37 for(int i=0;i<7;i++){ 38 if(abs(node.state[i].num)>abs(node.state[i+1].num)) 39 return false; 40 } 41 return true; 42 } 43 44 Node Get_Node(Node &p,int pos1,int pos2,int dir) 45 { 46 //pos1->pos2 left 47 if(dir==0){ 48 if(pos1<pos2){ 49 int tmp=p.state[pos1].num,flag=p.state[pos1].flag; 50 for(int i=pos1;i<=pos2-2;i++){ 51 p.state[i].num=p.state[i+1].num; 52 p.state[i].flag=p.state[i+1].flag; 53 } 54 p.state[pos2-1].num=tmp; 55 p.state[pos2-1].flag=flag; 56 }else { 57 int tmp=p.state[pos1].num,flag=p.state[pos1].flag; 58 for(int i=pos1;i>pos2;i--){ 59 p.state[i].num=p.state[i-1].num; 60 p.state[i].flag=p.state[i-1].flag; 61 } 62 p.state[pos2].num=tmp,p.state[pos2].flag=flag; 63 } 64 }else if(dir==1){ //pos1->pos2 right 65 if(pos1<pos2){ 66 int tmp=p.state[pos1].num,flag=p.state[pos1].flag; 67 for(int i=pos1;i<=pos2-1;i++){ 68 p.state[i].num=p.state[i+1].num; 69 p.state[i].flag=p.state[i+1].flag; 70 } 71 p.state[pos2].num=tmp,p.state[pos2].flag=flag; 72 }else { 73 int tmp=p.state[pos1].num,flag=p.state[pos1].flag; 74 for(int i=pos1;i>=pos2+2;i--){ 75 p.state[i].num=p.state[i-1].num; 76 p.state[i].flag=p.state[i-1].flag; 77 } 78 p.state[pos2+1].num=tmp,p.state[pos2+1].flag=flag; 79 } 80 } 81 return p; 82 } 83 84 85 void bfs() 86 { 87 memset(mark,false,sizeof(mark)); 88 queue<Node>que; 89 que.push(st); 90 mark[Get_Hash(st)]=true; 91 while(!que.empty()){ 92 Node q,pp,p=que.front(); 93 que.pop(); 94 if(Judge(p)){ 95 printf("%d\n",p.step); 96 return ; 97 } 98 for(int i=0;i<8;i++){ 99 for(int j=0;j<8;j++)if(i!=j){ 100 if(p.state[i].flag!=p.state[j].flag&&is_prime[abs(p.state[i].num)+abs(p.state[j].num)]){ 101 for(int k=0;k<2;k++){ 102 pp=p; 103 q=Get_Node(pp,i,j,k); 104 int val=Get_Hash(q); 105 q.step=p.step+1; 106 if(!mark[val]){ 107 mark[val]=true; 108 que.push(q); 109 } 110 } 111 } 112 } 113 } 114 } 115 puts("-1"); 116 } 117 118 119 int main() 120 { 121 int _case,t=1; 122 scanf("%d",&_case); 123 while(_case--){ 124 for(int i=0;i<8;i++){ 125 scanf("%d",&st.state[i].num); 126 st.state[i].flag=(st.state[i].num>0?1:-1); 127 } 128 st.step=0; 129 printf("Case %d: ",t++); 130 bfs(); 131 } 132 return 0; 133 }