六数码问题

来源:互联网 发布:摇滚音乐淘宝网 编辑:程序博客网 时间:2024/05/24 06:35

六数码问题

时限:1000ms 内存限制:10000K 总时限:3000ms

描述:

现有一两行三列的表格如下:

A B C
D E F

把1、2、3、4、5、6六个数字分别填入A、B、C、D、E、F格子中,每个格子一个数字且各不相同。每种不同的填法称为一种布局。如下:

1 3 5
2 4 6
布局1

2 5 6
4 3 1
布局2

定义α变换如下:把A格中的数字放入B格,把B格中的数字放入E格,把E格中的数字放入D格,把D格中的数字放入A格。
定义β变换如下:把B格中的数字放入C格,把C格中的数字放入F格,把F格中的数字放入E格,把E格中的数字放入B格。

问:对于给定的布局,可否通过有限次的α变换和β变换变成下面的目标布局:

1 2 3
4 5 6
目标布局

输入:

本题有多个测例,每行一个,以EOF为输入结束标志。每个测例的输入是1到6这六个数字的一个排列,空格隔开,表示初始布局ABCDEF格中依次填入的数字。

输出:

每个输出占一行。可以转换的,打印Yes;不可以转换的,打印No。

输入样例:

1 3 5 2 4 62 5 6 4 3 1

输出样例:

NoYes

#include<iostream>#include<stdio.h>#include<queue>#include<map>using namespace std;queue<int>q1;map<int,int>step;int a[6];void init();int bfs();int mov(int u,int i);int main(){  int i,j=0;  int b[50]; while(scanf("%d",&a[0])!=EOF) {  for(i=1;i<=5;i++)  {    scanf("%d",&a[i]);  }  init();  if(bfs()==1)  {  b[j]=1;  j+=1;  }  else  {  b[j]=0;  j+=1;  } } for(i=0;i<j;i++) {  if(b[i]==1)  {   cout<<"Yes"<<endl;  }  else  {   cout<<"No"<<endl;  } }}void init(){  int i,sum=0;  for(i=0;i<6;i++)   {    sum=sum*10+a[i];   }   q1.push(sum);   step[sum]=1;}int bfs(){ int u,v,i;   while(!q1.empty())  {   u=q1.front();   q1.pop();   if(u==123456)   {    return 1;   }   for(i=0;i<2;i++)   {      v=mov(u,i);      if(v==123456)   {    while(!q1.empty())    {     q1.pop();    }   step.erase(step.begin(), step.end());   return 1;   }   if(step.count(v)==0)   {   q1.push(v);   step[v]=1;      }   }  } return -1;}int mov(int u,int i){ int j,k,num=0,sum=0,m; m=u; int c[2][3]; for(j=1;j>=0;j--) {  for(k=2;k>=0;k--)  {   c[j][k]=m%10;   m=m/10;  } } if(i==0) {   num=c[0][1];   c[0][1]=c[0][0];   sum=c[1][1];   c[1][1]=num;   num=c[1][0];   c[1][0]=sum;   c[0][0]=num;    } if(i==1) {    num=c[0][2];   c[0][2]=c[0][1];   sum=c[1][2];   c[1][2]=num;   num=c[1][1];   c[1][1]=sum;   c[0][1]=num; } sum=0; for(j=0;j<2;j++) {  for(k=0;k<3;k++)  {   sum=sum*10+c[j][k];  } } return sum;
}
v