您的位置:首页 > 其它

SSL-ZYC 1692 魔板

2018-03-07 15:51 309 查看
题目大意:

对于一个2*4的魔板,你有三种操作:

A 交换上下两行

B 将最右边的一列插入最左边

C 魔板中央四格作顺时针旋转

已知

1234
8765


为魔板复原的样子,现在给出一个魔板,要求输出复原的最少步数以及依次进行的操作。

思路

这道题我听地真的很懵。。。

正解是BFS+HASH,从复原的样子开始搜索,把三种变化方法都搜一遍,直到成为了输入的样子(此时的方案绝对是最优方案),然后递归输出。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int k=40319;
int c[4][9],sum,x,father[k],ha[k],way[k],head,state[k][9],tail;
char a[k][9],b[k];

void csh()  //初始化
{
c[1][1]=8;
c[1][2]=7;
c[1][3]=6;
c[1][4]=5;
c[1][5]=4;
c[1][6]=3;
c[1][7]=2;
c[1][8]=1;

c[2][1]=4;
c[2][2]=1;
c[2][3]=2;
c[2][4]=3;
c[2][5]=6;
c[2][6]=7;
c[2][7]=8;
c[2][8]=5;

c[3][1]=1;
c[3][2]=7;
c[3][3]=2;
c[3][4]=4;
c[3][5]=5;
c[3][6]=3;
c[3][7]=6;
c[3][8]=8;  //所有变化情况
}

int h(int x)  //哈希函数
{
return x%k;
}

int locate(int x)  //查找
{
int m=0;
for (int i=1;i<=8;i++)
m=m*10+state[x][i];  //取出该情况
int t=h(m);  //求出储存位置
int i=0;
while (i<k&&ha[(i+t)%k]!=m&&ha[(i+t)%k]!=0) i++;  //找到一个符合的情况才退出
if (ha[(i+t)%k]==m) return 1;  //如果查找到(即这种情况已经用更少步的方法得到就返回1)
else
{
ha[(i+t)%k]=m;  //储存
return 0;  //返回0
}
}

void print(int x)  //递归输出
{
if (x==1) return;  //已经无法递归的话就返回
sum++;  //计数
if (way[x]==1) b[sum]='A';
if (way[x]==2) b[sum]='B';
if (way[x]==3) b[sum]='C';  //判断
print(father[x]);  //递归
}

void bfs()
{
head=0;
tail=1;
father[1]=0;
way[1]=0;
for (int i=1;i<=8;i++) state[1][i]=i;  //初始化
do
{
head++;
for (int i=1;i<=3;i++)  //枚举每种变化
{
tail++;
way[tail]=i;  //记录路径
father[tail]=head;  //记录父节点
for (int j=1;j<=8;j++)
state[tail][j]=state[head][c[i][j]];  //更改魔板情况
tail-=locate(tail);  //等于 if (locate(tail)==1) tail--;
int ok=0;
for (int i=1;i<=8;i++)  //判断是否已经完成
if (state[tail][i]!=state[0][i])
{
ok=1;
break;
}
if (ok==0)
{
print(tail);  //输出
tail=-1;
return;
}
}
}
while (head<tail);
}

int main()
{
csh();
int o=0;
for (int i=1;i<=8;i++)
{
scanf("%d",&state[0][i]);
o=o*10+state[0][i];
}
if (o==12345678)  //特殊判断
{
printf("0\n\n");
return 0;
}
bfs();
printf("%d\n",sum);
for (int i=sum;i>=1;i--)
{
putchar(b[i]);
if (i%60==0) printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: