不容易看出来的搜索类题目,求达到满足题意的最短的步数,很明显的广搜做最优。
题意:一个正方体每个面代表一个数字1~6,按顺序上下左右前后,四种翻转方式,问最少经过多少次翻转能到达目标状态,不能到达就输出-1.
这题难点,在于每个状态的表示,和转换方式,和判断方法,好的代码可以简略又清晰,差的代码就如我般臃肿又难懂。。。太弱了
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int s1[7],s2[7],book[7][7][7][7][7][7],flag;
struct node
{
int a[7],step;
};
queue<node>Q;
node change(node c,int k)
{
node temp;
if(k==0)
{
temp.a[1]=c.a[3];
temp.a[2]=c.a[4];
temp.a[3]=c.a[2];
temp.a[4]=c.a[1];
temp.a[5]=c.a[5];
temp.a[6]=c.a[6];
}
if(k==1)
{
temp.a[1]=c.a[6];
temp.a[2]=c.a[5];
temp.a[3]=c.a[3];
temp.a[4]=c.a[4];
temp.a[5]=c.a[1];
temp.a[6]=c.a[2];
}
if(k==2)
{
temp.a[1]=c.a[4];
temp.a[2]=c.a[3];
temp.a[3]=c.a[1];
temp.a[4]=c.a[2];
temp.a[5]=c.a[5];
temp.a[6]=c.a[6];
}
if(k==3)
{
temp.a[1]=c.a[5];
temp.a[2]=c.a[6];
temp.a[3]=c.a[3];
temp.a[4]=c.a[4];
temp.a[5]=c.a[2];
temp.a[6]=c.a[1];
}
return temp;
}
void bfs()
{
while(!Q.empty()) Q.pop();
node first;
for(int i=1;i<=6;i++)
first.a[i]=s1[i];
first.step=0;
Q.push(first);
while(!Q.empty())
{
node now,next;
now=Q.front();
Q.pop();
if(now.a[1]==s2[1]&&now.a[2]==s2[2]&&now.a[3]==s2[3]&&now.a[4]==s2[4]&&now.a[5]==s2[5]&&now.a[6]==s2[6])
{
printf("%d\n",now.step);
flag=1;
return;
}
else
{
for(int i=0;i<4;i++)
{
next=change(now,i);
if(!book[next.a[1]][next.a[2]][next.a[3]][next.a[4]][next.a[5]][next.a[6]])
{
book[next.a[1]][next.a[2]][next.a[3]][next.a[4]][next.a[5]][next.a[6]]=1;
next.step=now.step+1;
Q.push(next);
}
}
}
}
}
int main()
{
while(~scanf("%d",&s1[1]))
{
flag=0;
for(int i=2;i<=6;i++)
scanf("%d",&s1[i]);
for(int i=1;i<=6;i++)
scanf("%d",&s2[i]);
memset(book,0,sizeof(book));
bfs();
if(!flag)
printf("-1\n");
}
}