NPU 程序设计17届 1045 六数码问题

来源:互联网 发布:淘宝店有差评怎么办 编辑:程序博客网 时间:2024/05/24 04:48

Problem E

六数码问题

时限: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

本题的主要难点在于,如何将六数码图的数据储存起来。经过查阅资料,以及之前在课上八皇后用一维数组储存数据、用二进制的双精度数(100001000....)储存真值表,发现本题的数据可以用一个变量储存在队列内。如2 5 6/n 4 3 1/n,我们可以直接用256431储存。由于本身六数码图每个位置有特定的顺序,我们可以很容易将这个储存用的变量还原为六数码图。

#include<iostream>#include<cstdio>#include<queue>#include<map>using namespace std;queue<int> q;//数组可以储存当前6数码图的形态 map<int,int> used;//map函数用来一一对应每一种可能出现的6数码图情况并标记已被使用 void init(int num);int bfs();int change(int u,int i);int main(){int first,num,i,result;while (scanf("%d",&first)!=EOF){//如果没有输入则结束程序 num = first;//将第一个输入的数放入 for (i = 0;i < 5;i++){//先乘10,再将新输入的数加进去,形成我们想要的储存形式 num = num * 10; cin >> first;num = num + first;}while (!q.empty()){q.pop();}used.clear();//每次使用前先将map清空防止干扰 init(num);result = bfs();if (result == 1){cout << "Yes" << endl;}else if (result == 0){cout << "No" << endl;}}return 0;}void init(int num){//将初始的情况放入数组并标记已使用 q.push(num);used[num] = 1; }int bfs(){int u,v,i;while (!q.empty()){u = q.front();q.pop();for (i = 0;i < 2;i++){v = change(u,i);if (v == 123456){//如果等于我们想要的情况,返回1 return 1;}else if (v != 123456 && used[v] != 1){//将经过变换得到的图放入队列并标记 q.push(v);used[v] = 1;}}}//如果所有经过α,β变换生成的图都不符合要求,则返回0 return (0);}int change(int u,int i){int nowmap[2][3],j,k,num;int newmap[2][3];//将储存在一个变量的数据恢复为6数码的二维数组形态 for (j = 1;j >= 0;j--){for (k = 2;k >= 0;k--){num = u % 10;nowmap[j][k] = num;newmap[j][k] = num;u = u / 10;}}if (i == 0){//α变换 newmap[0][0] = nowmap[1][0];newmap[0][1] = nowmap[0][0];newmap[1][1] = nowmap[0][1];newmap[1][0] = nowmap[1][1];}if (i == 1){//β变换 newmap[0][1] = nowmap[1][1];newmap[0][2] = nowmap[0][1];newmap[1][2] = nowmap[0][2];newmap[1][1] = nowmap[1][2];}num = 0;//将变换后的二维数组储存在一个变量内 for (j = 0;j < 2;j++){for (k = 0;k < 3;k++){num = num * 10;num = num + newmap[j][k];}}return (num);}