您的位置:首页 > 其它

sicily 1150. 简单魔板

2015-10-21 12:19 417 查看

1150. 简单魔板

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

魔板由8个大小相同方块组成,分别用涂上不同颜色,用1到8的数字表示。

其初始状态是

1 2 3 4

8 7 6 5

对魔板可进行三种基本操作:

A操作(上下行互换):

8 7 6 5

1 2 3 4

B操作(每次以行循环右移一个):

4 1 2 3

5 8 7 6

C操作(中间四小块顺时针转一格):

1 7 2 4

8 6 3 5

用上述三种基本操作,可将任一种状态装换成另一种状态。

Input

输入包括多个要求解的魔板,每个魔板用三行描述。

第一行步数N(不超过10的整数),表示最多容许的步数。

第二、第三行表示目标状态,按照魔板的形状,颜色用1到8的表示。

当N等于-1的时候,表示输入结束。

Output

对于每一个要求解的魔板,输出一行。

首先是一个整数M,表示你找到解答所需要的步数。接着若干个空格之后,从第一步开始按顺序给出M步操作(每一步是A、B或C),相邻两个操作之间没有任何空格。

注意:如果不能达到,则M输出-1即可。

Sample Input


45 8 7 64 1 2 338 7 6 51 2 3 4-1

Sample Output


2 AB1 A


题目分析

求由初始状态变为给定状态需要几步

注意到初始状态为

1234

8765

题目输入的是结束状态,同时其要求解法是在给定步数内,

所以当入队列的状态的步数超过了,可以提前结束搜索,

#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>

std::vector<std::string> visited;

bool unvisited(std::string data) {
std::vector<std::string>::iterator res = find(visited.begin(), visited.end(), data);
return res == visited.end();
}

std::string change(std::string init, char c) {
std::string str = "";
if (c == 'A')
str = str + init[4] + init[5] + init[6] + init[7] + init[0] + init[1] + init[2] + init[3];
else if (c == 'B')
str = str + init[3] + init[0] + init[1] + init[2] + init[7] + init[4] + init[5] + init[6];
else
str = str + init[0] + init[5] + init[1] + init[3] + init[4] + init[6] + init[2] + init[7];
return str;
}

int main()
{
int steps;
std::string init = "12348765";
char c;
while (scanf("%d", &steps)) {
if (steps == -1)
break;
int ans;
std::string target = "";
for (int i = 0; i < 8; ++i) {
scanf("%d", &ans);
c = '1' + ans - 1;
target = target + c;
}
if (init == target) {
if (0 >= steps)
printf("0\n");
else
printf("-1\n");
continue;
}
if (!visited.empty())
visited.clear();

std::queue<std::string> q;
std::queue<std::string> path;
q.push(init);
path.push("");
visited.push_back(init);
std::string sol = "";
bool flag = true;
while (!q.empty() && flag) {
std::string state = q.front();
q.pop();
std::string nowpath = path.front();
path.pop();

std::string newstate;
std::string newpath;
for (int i = 0; i < 3; ++i) {
c = 'A' + i;
newstate = change(state, c);
newpath = nowpath + (c);
if (newpath.length() > steps) {
flag = false;
break;
}
if (newstate == target) {
sol = newpath;
flag = false;
break;
}
if (unvisited(newstate)) {
//std::cout << newstate << std::endl;
q.push(newstate);
path.push(newpath);
visited.push_back(newstate);
}
}
}
if (sol.length() <= steps && !flag)
std::cout << sol.length() << " " << sol << std::endl;
else
printf("-1\n");
}
}


4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: