bool vis[50000];//判重数组
int fac[15] = {1,1,2,6,24,120,720,5040,40320,362880};//记录0~9的阶乘
int final[9];//我们需要转换到的魔板状态
char ans[10];//用于输出
struct status { //每个结点表示该魔板的状态
int a[9]; //魔板上的数字
int step;//已变换步数
int father;//其前驱
char op;//上一步做的转换
} sta[50000];
status A(status x) {
for(int i=1; i<=4; i++)
swap(x.a[i],x.a[9-i]);
return x;
}
status B(status x) {
for(int i=4; i>=2; i--) {
swap(x.a[i-1],x.a[i]);
swap(x.a[9-i],x.a[10-i]);
}
return x;
}
status C(status x) {
swap(x.a[3],x.a[2]);
swap(x.a[7],x.a[6]);
swap(x.a[2],x.a[6]);
return x;//题目所说三种变换
}
int Cantor(status x) {
int s = 1;
int sum = 1; //sum从1开始
for(int i = 1; i <= 8; i++) {
s = 0;
for(int j = i+1; j<=8; j++) {
if(x.a[j] < x.a[i])
s++;
}
sum +=s * fac[8-i];
}
return sum;
}
void print(status x) {
int s=1;
while(x.father!=-1) {
ans[s]=x.op;
s++;
x=sta[x.father];
}
for(int i=s-1; i>=1; i--) {
cout<<ans[i];
}
return;
}
int main() {
for(int i=1; i<=8; i++)
cin>>final[i];
int front=0,rear=0;
for(int i=1; i<=8; i++)
sta[rear].a[i]=i;
sta[rear].step=0;
sta[rear].father=-1;//初始化
rear++;
bool find=1;
for(int i=1; i<=8; i++) {
if(sta[front].a[i]!=final[i]) {
find=0;
break;
}
}
if(find) {
cout<<sta[front].step;
print(sta[front]);
return 0;
}
while(front<rear) { //队列不空
for(int i=1; i<=3; i++) {
status temp;
if(i==1) temp=A(sta[front]);
if(i==2) temp=B(sta[front]);
if(i==3) temp=C(sta[front]);
int k=Cantor(temp);
if(!vis[k]) {
vis[k]=1;
sta[rear]=temp;
sta[rear].step=sta[front].step+1;
sta[rear].father=front;//记录该状态的前驱(前一步)
sta[rear].op='A'+i-1;
find=1;
for(int i=1; i<=8; i++) {
if(temp.a[i]!=final[i]) {
find=0;
break;
}
}
if(find) {
cout<<sta[rear].step<<endl;
print(sta[rear]);
return 0;
}
rear++;
}
}
front++;
}
return 0;
}
魔板问题c++
最新推荐文章于 2025-04-25 21:12:48 发布