您的位置:首页 > 编程语言 > C语言/C++

C语言中用队列和广搜解决六数码问题。

2017-11-10 18:27 239 查看
描述

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

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 6

2 5 6 4 3 1

输出样例

No

Yes

要注意有多组数据的时候,要清空队列和map,不能让上一组留下的痕迹影响下一组数据。

#include<iostream>
#include<stdio.h>
#include<queue>
#include<map>
#include<math.h>

using namespace std;

queue<int> q;
map<int,int> used;//map用来记录状态有没有达到过

void init(int num);
int bfs();
int moveto(int u,int i);
void print(int n);

int main()
{
int temp,num=0,i;
while(scanf("%d",&temp)!=EOF)//以EOF为结束标志
{
num=temp*pow(10,5);
for(i=4;i>=0;i--)
{
scanf("%d",&temp);
num+=temp*pow(10,i);
}//将输入的布局直接转为6位数

while(!q.empty())
{
q.pop();
}
used.clear();//因为有多组数据,所以每次搜索之前要清空队列和map

init(num);//初始化
print(bfs());//输出搜索的结果
}
return 0;
}

void init(int num)
{
q.push(num);//将起点加入队列
used[num]=1;//将起点标注为以使用过
}

int bfs()
{
int u,v,i;
while(!q.empty())
{
u=q.front();//u取队首元素
q.pop();//输出队首元素
for(i=1;i<=2;i++)//1为α变换,2为β变换
{
v=moveto(u,i);//v为u经过变换后的新状态
if(v==123456) return 1;//搜索到答案,返回1
if(used.count(v)==0)//v是新状态
{
q.push(v);//把新状态加入队列
used[v]=1;//标记新状态已经用过
}
}
}
return 0;//队列已经为空,没有搜索到答案,返回0
}

void print(int n)
{
if(n==0) printf("No\n");
if(n==1) printf("Yes\n");
//bfs函数中找到答案输出Yes没找到输出No
}

int moveto(int u,int i)
{
int bj[3][4],m,n,num=0;
for(m=2;m>=1;m--)
{
for(n=3;n>=1;n--)
{
bj[m]
=u%10;
u=u/10;
}
}//先把6位数转换成数组布局
if(i==1)
{
int a,b,e,d;
a=bj[1][1];
b=bj[1][2];
e=bj[2][2];
d=bj[2][1];
bj[1][1]=d;
bj[1][2]=a;
bj[2][2]=b;
bj[2][1]=e;
}//α变换
if(i==2)
{
int b,c,e,f;
b=bj[1][2];
c=bj[1][3];
e=bj[2][2];
f=bj[2][3];
bj[1][2]=e;
bj[1][3]=b;
bj[2][3]=c;
bj[2][2]=f;
}//β变换
for(m=1;m<=2;m++)
{
for(n=1;n<=3;n++)
{
num=num*10+bj[m]
;
}
}//再将数组布局转换回6位数
return num;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 队列 广搜