这道题目,以前写过类似的。所以这次看了题目后,还是有头绪的。
不过这道真的很麻烦啊!
用到了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;
}