这道题目,以前写过类似的。所以这次看了题目后,还是有头绪的。
不过这道真的很麻烦啊!
用到了Hash + BFS
1、2、3、4、5、6、7、8不管将它们怎样变换,最多也就8! = 40320 种情况,所以可以使用BFS算法枚举下,打表即可。这是总的思想。
但1……8是字符串,不好打表,所以这时就用到了Hash算法,我用的字符串转化算法是从一位大牛那拷过来,挺好的。
其它不需要解释了!
hehe....
源代码好下:
/* ID: guo geer PROG: msquare LANG: C++ */ #include<iostream> #include<fstream> #include<string> #include<cstring> using namespace std; string ans[40320]; int jc[8] = {1, 1, 2, 6, 24, 120, 720, 5040}; int Encode(int s[]) { int sum = 0; for(int i=0; i<8; i++) { int count = 0; for(int j=i; j<8; j++) if(s[i] > s[j]) count ++; sum += jc[7-i]*count; } return sum; } void Decode(int s[], int n) { for(int i=0; i<8; i++) { s[i] = n/jc[7-i]; n %= jc[7-i]; } for(int i=7; i>=0; i--) for(int j=i+1; j<8; j++) if(s[i] <= s[j]) s[j] ++; } void Exchange(int s[], int n) { int i,j,k; int tmp[8]; switch(n) { case 0: for(i=0; i<8; i++) tmp[i] = s[7-i]; memcpy(s, tmp, 8*sizeof(int)); break; case 1: tmp[0] = s[3], tmp[1] = s[0], tmp[2] = s[1], tmp[3] = s[2]; tmp[4] = s[5], tmp[5] = s[6], tmp[6] = s[7], tmp[7] = s[4]; memcpy(s, tmp, 8*sizeof(int)); break; case 2: tmp[0] = s[0], tmp[1] = s[6], tmp[2] = s[1], tmp[3] = s[3]; tmp[4] = s[4], tmp[5] = s[2], tmp[6] = s[5], tmp[7] = s[7]; memcpy(s, tmp, 8*sizeof(int)); break; } } void BFS() { int i,j,k; for(i=0; i<40320; i++) ans[i] = ""; int q[100000]; int r, r1, f; r = r1 = f = 0; int init[8] = {0, 1, 2, 3, 4, 5, 6, 7}; k = Encode(init); q[0] = k; int steps = 0; while(true) { ++steps; ++r; while(f != r) { for(int x=0; x<3; x++) { Decode(init, q[f]); Exchange(init, x); k = Encode(init); if(ans[k].length() == 0 && k != q[0]) { q[++r1] = k; ans[k] = ans[q[f]] + (char)('A' + x); } } ++f; } if(r == r1 + 1) return; r = r1; } } int main() { ifstream fin("msquare.in"); ofstream fout("msquare.out"); BFS(); int i,j,k; int data[8]; for(i=0; i<8; i++) { fin>>data[i]; data[i] -- ; } k = Encode(data); //cout<<ans[k]<<endl; // cout<<k<<endl; fout<<ans[k].length()<<endl; for(i=0; ans[k][i] != '\0'; i++) { if(i%60 == 0 && i != 0) fout<<endl; fout<<ans[k][i]; } fout<<endl; //system("pause"); return 0; }