sicily 简单魔板2
sicily上面的三道“简单魔板”的变形,开始以为数据变大了第一道题的解法行不通了,其实不然。网上看到用康托展开来进行存储状态的,发现其实对于这道题没能发挥康托展开的强大威力。
下面是找到别人的代码,自己加了一些注释(呜呜,我不想剽窃的。。。只是转载不了。。)
关于康托展开,百度百科讲得非常详细了,看下就知道是什么东西了,算法实现也很简单,主要是其思想。。
其实这道题没必要使用康托编码,这里没发挥它的强大作用。因为从开始状态往下一层一层的搜不会出现太多的状态(试了下1000000步
也只是一万多种状态而已,所以康托编码没太多作用对于这道题)
1 #include<iostream> 2 #include<string> 3 #include<queue> 4 #include<memory.h> 5 using namespace std; 6 struct Board 7 { 8 int x[4]; 9 int y[4]; 10 string way; 11 const Board operator=(const Board &p) 12 { 13 x[0]=p.x[0]; 14 x[1]=p.x[1]; 15 x[2]=p.x[2]; 16 x[3]=p.x[3]; 17 y[0]=p.y[0]; 18 y[1]=p.y[1]; 19 y[2]=p.y[2]; 20 y[3]=p.y[3]; 21 way=p.way; 22 return *this; 23 } 24 }; 25 int n; 26 int x[4],y[4]; 27 Board q; 28 bool isvisit[50000];//用于搜索某状态是否曾经出现过 29 int fact[]={1,1,2,6,24,120,720,5040,40320};//8的阶乘表 30 //康托展开 31 int encode(Board p) 32 { 33 int sum=0; 34 int cnt; 35 int tmp[8]; 36 for(int i=0;i<4;i++) 37 { 38 tmp[i]=p.x[i]; 39 tmp[4+i]=p.y[i]; 40 } 41 for(int i=0;i<7;i++) //真正的康托展开在这里开始 42 { 43 cnt=0; 44 for(int j=i+1;j<8;j++) 45 if(tmp[i]>tmp[j]) cnt++; //往低位寻找比它小的数字的个数 46 sum+=fact[8-i-1]*cnt; //比它小的数字数目乘以相应的阶乘 47 } 48 return sum; 49 } 50 //a 51 void a(Board p) 52 { 53 q.x[0]=p.y[0]; 54 q.x[1]=p.y[1]; 55 q.x[2]=p.y[2]; 56 q.x[3]=p.y[3]; 57 q.y[0]=p.x[0]; 58 q.y[1]=p.x[1]; 59 q.y[2]=p.x[2]; 60 q.y[3]=p.x[3]; 61 q.way=p.way+"A"; 62 } 63 //b 64 void b(Board p) 65 { 66 q.x[0]=p.x[3]; 67 q.x[1]=p.x[0]; 68 q.x[2]=p.x[1]; 69 q.x[3]=p.x[2]; 70 q.y[0]=p.y[3]; 71 q.y[1]=p.y[0]; 72 q.y[2]=p.y[1]; 73 q.y[3]=p.y[2]; 74 q.way=p.way+"B"; 75 } 76 //c 77 void c(Board p) 78 { 79 q.x[0]=p.x[0]; 80 q.x[3]=p.x[3]; 81 q.y[0]=p.y[0]; 82 q.y[3]=p.y[3]; 83 q.x[1]=p.y[1]; 84 q.x[2]=p.x[1]; 85 q.y[1]=p.y[2]; 86 q.y[2]=p.x[2]; 87 q.way=p.way+"C"; 88 } 89 bool equal(Board p) 90 { 91 for(int i=0;i<4;i++) 92 { 93 if(p.x[i]!=x[i]) 94 return false; 95 if(p.y[i]!=y[i]) 96 return false; 97 } 98 return true; 99 } 100 void bfs() 101 { 102 Board p; 103 p.x[0]=1; 104 p.x[1]=2; 105 p.x[2]=3; 106 p.x[3]=4; 107 p.y[0]=8; 108 p.y[1]=7; 109 p.y[2]=6; 110 p.y[3]=5; 111 p.way=""; 112 113 queue<Board> magic; 114 isvisit[encode(p)]=true; 115 magic.push(p); 116 while(!magic.empty()) 117 { 118 p=magic.front(); 119 magic.pop(); 120 if(p.way.size()>n) 121 { 122 cout<<"-1"<<endl; 123 return; 124 } 125 if(equal(p)) 126 { 127 cout<<p.way.size()<<" "<<p.way<<endl; 128 return; 129 } 130 a(p); 131 if(!isvisit[encode(q)]) 132 { 133 isvisit[encode(q)]=true; 134 magic.push(q); 135 } 136 137 b(p); 138 if(!isvisit[encode(q)]) 139 { 140 isvisit[encode(q)]=true; 141 magic.push(q); 142 } 143 144 c(p); 145 if(!isvisit[encode(q)]) 146 { 147 isvisit[encode(q)]=true; 148 magic.push(q); 149 } 150 } 151 } 152 153 int main() 154 { 155 while(cin>>n&&n!=-1) 156 { 157 memset(isvisit,false,sizeof(isvisit)); 158 cin>>x[0]>>x[1]>>x[2]>>x[3]; 159 cin>>y[0]>>y[1]>>y[2]>>y[3]; 160 bfs(); 161 } 162 return 0; 163 }