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

4
5 8 7 6
4 1 2 3
3
8 7 6 5
1 2 3 4
-1

Sample Output

2  AB
1 A
 #include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
/* 魔板状态结构体 */
struct State {
int x, y; // 魔板上下两行的状态
string op; // 从初始状态到达此状态的操作序列
State() {}
State(int a, int b, string str) : x(a), y(b), op(str) {}
} states[]; /* 判断states[index]是否为目标状态 */
bool ok(int x, int y, int index) {
if (states[index].x == x && states[index].y == y)
return true;
return false;
} /* 康托展开 , 代码参考百度百科*/
/*(n-1)!, 1 <= n <= 8*/
int factory[] = { , , , , , , , };
int cantor(int x) {
int buf[];
/* 拆成8位, */
for (int i = ; i < ; i++) {
int p = (int)pow(, -i);
buf[i] = x / p;
x = x % p;
}
int id = ;
/* 计算康托展开 */
for (int i = ; i < ; i++) {
int count = ;
for (int j = i + ; j < ; j++)
if (buf[i] > buf[j]) count++;
id = id + count*factory[ - - i];
}
return id;
} /*A、B、C操作*/
void A(int &m, int &n, int fp) {
m = states[fp].y;
n = states[fp].x;
}
void B(int &m, int &n, int fp) {
m = (states[fp].x % ) * + (states[fp].x / );
n = (states[fp].y % ) * + (states[fp].y / );
}
void C(int &m, int &n, int fp) {
int i = (states[fp].x / )*;
int j = states[fp].x - i;
int a = j / ;
int b = (j - a * ) / ;
int i1 = (states[fp].y / ) * ;
int j1 = states[fp].y - i1;
int c = j1 / ;
int d = (j1 - c * ) / ;
m = i + c * + a * + (states[fp].x % );
n = i1 + d * + b * + (states[fp].y % );
} int main() {
int N;
while (cin >> N && N != -) {
int x = , y = , temp; // x,y记录目标魔板状态,temp:临时变量,用于从标准输入流提取数据
bool flag = false; // 标志位,true表示到达目标状态,结束搜索
bool visited[]; // 记录魔板是否已被搜索
for (int i = ; i < ; i++) visited[i] = false; // 初始化为未被搜索,即false。
for (int i = ; i < ; i++) { // 输入数据
cin >> temp;
x = x* + temp;
}
for (int i = ; i < ; i++) {
cin >> temp;
y = y* + temp;
}
if (x == && y == ) flag = true;
/* fp:头指针,即当前处理的魔板下标;rp:尾指针;l: 到达当前状态所用的步数 */
int fp = , rp = , l = ;
states[fp] = State(, ,"");
visited[cantor()] = true;
while (l < N && !flag) { //
int m = states[fp].x;
int n = states[fp].y;
/* A操作,A(int&,int&,int). 参数为引用,所以 m 和 n 的值会被改变, B,C 同理 */
A(m, n, fp);
/*
若操作后状态未被搜索, 则进队,尾指针(下标)加 1。
同时visited[index]置为true.
若为目标状态,则标志位置为true,表示找到解,同时结束循环
B,C同理
*/
if (!visited[cantor(m*+n)]) {
states[++rp] = State(m, n, states[fp].op+"A");
visited[cantor(m*+n)] = true;
if (ok(x, y, rp)) {
flag = true;
break;
}
}
B(m, n, fp);
if (!visited[cantor(m*+n)]) {
states[++rp] = State(m, n, states[fp].op+"B");
visited[cantor(m*+n)] = true;
if (ok(x, y, rp)) {
flag = true;
break;
}
}
C(m, n, fp);
if (!visited[cantor(m*+n)] ) {
states[++rp] = State(m, n, states[fp].op+"C");
visited[cantor(m*+n)] = true;
if (ok(x, y, rp)) {
flag = true;
break;
}
}
l = states[fp++].op.size(); // 计算到达当前状态需要的步数 然后头指针移到下一位
}
if (flag) cout << states[rp].op.size() << " " << states[rp].op << endl;
else cout << "-1" << endl;
}
}

Sicily 1151 魔板的更多相关文章

  1. Sicily 1051: 魔板(BFS+排重)

    相对1150题来说,这道题的N可能超过10,所以需要进行排重,即相同状态的魔板不要重复压倒队列里,这里我用map储存操作过的状态,也可以用康托编码来储存状态,这样时间缩短为0.03秒.关于康托展开可以 ...

  2. Sicily 1150: 简单魔板(BFS)

    此题可以使用BFS进行解答,使用8位的十进制数来储存魔板的状态,用BFS进行搜索即可 #include <bits/stdc++.h> using namespace std; int o ...

  3. Sicily1151:魔板搜索及优化

    最终优化代码地址: https://github.com/laiy/Datastructure-Algorithm/blob/master/sicily/1151.c 题目如下 Constraints ...

  4. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  5. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. [HDU 1430] 魔板

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  7. hdu1430魔板(BFS+康托展开)

    做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...

  8. 【USACO 3.2.5】魔板

    [描述] 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个 ...

  9. HDU_1430——魔板,预处理,康托展开,置换,string类的+操作

    Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可 ...

随机推荐

  1. iOS 之 Swift 新特性

    支持所有C和OC的基本类型 提供了Array 和Dictionary两个强劲的集合类型 元组 可选类型 闭包 脚本特性 类型安全

  2. Delphi 常用API 函数

    Delphi 常用API 函数 AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小 AnyPopup 判断屏幕上是否存在任何弹出式窗口 ArrangeIconic ...

  3. jQuery学习笔记之jQuery.fn.init()的参数分析

    这篇文章主要介绍了jQuery.fn.init()的参数分析,需要的朋友可以参考下   从return new jQuery.fn.init( selector, context, rootjQuer ...

  4. ui-router---$stateProvider

    转自:http://blog.csdn.net/violet_day/article/details/17515157 $stateProvider $stateProvider.state(stat ...

  5. Camera.ScreenPointToRay 解析

    Unity官方文档: Camera.ScreenPointToRay public function ScreenPointToRay(position: Vector3): Ray; Descrip ...

  6. IM比较SipDroid/IMSDroid/CSipsimple/Linphone/Webrtc

    一) sipdroid1)架构sip协议栈使用JAVA实现,音频Codec使用skype的silk(Silk编解码是Skype向第三方开发人员和硬件制造商提供免版税认证(RF)的Silk宽带音频编码器 ...

  7. PariticalFilter在MFC上的运行,源代码公开

    由于项目需要,进行过一段时间的 PariticalFilter 研究.主要的工作就是将网络上的Console代码和Mfc融合在一起,并且添加了Mfc端的控制功能.       程序还有不完善的地方,现 ...

  8. OGG学习笔记04-OGG复制部署快速参考

    OGG学习笔记04-OGG复制部署快速参考 源端:Oracle 10.2.0.5 RAC + ASM 节点1 Public IP地址:192.168.1.27 目标端:Oracle 10.2.0.5 ...

  9. 【开源.NET】 分享一个前后端分离的轻量级内容管理框架

    开发框架要考虑的面太多了:安全.稳定.性能.效率.扩展.整洁,还要经得起实践的考验,从零开发一个可用的框架,是很耗时费神的工作.网上很多开源的框架,为何还要自己开发?我是基于以下两点: 没找到合适的: ...

  10. [转载]【虚拟化系列】VMware vSphere 5.1 简介与安装

    转载自:http://mabofeng.blog.51cto.com/2661587/1017680 一. VMware vSphere 5.1简介           vSphere是VMware推 ...