Sicily 1151 魔板
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 魔板的更多相关文章
- Sicily 1051: 魔板(BFS+排重)
相对1150题来说,这道题的N可能超过10,所以需要进行排重,即相同状态的魔板不要重复压倒队列里,这里我用map储存操作过的状态,也可以用康托编码来储存状态,这样时间缩短为0.03秒.关于康托展开可以 ...
- Sicily 1150: 简单魔板(BFS)
此题可以使用BFS进行解答,使用8位的十进制数来储存魔板的状态,用BFS进行搜索即可 #include <bits/stdc++.h> using namespace std; int o ...
- Sicily1151:魔板搜索及优化
最终优化代码地址: https://github.com/laiy/Datastructure-Algorithm/blob/master/sicily/1151.c 题目如下 Constraints ...
- hdu.1430.魔板(bfs + 康托展开)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU 1430 魔板(康托展开+BFS+预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- [HDU 1430] 魔板
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- hdu1430魔板(BFS+康托展开)
做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...
- 【USACO 3.2.5】魔板
[描述] 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个 ...
- HDU_1430——魔板,预处理,康托展开,置换,string类的+操作
Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可 ...
随机推荐
- spark在集群上运行
1.spark在集群上运行应用的详细过程 (1)用户通过spark-submit脚本提交应用 (2)spark-submit脚本启动驱动器程序,调用用户定义的main()方法 (3)驱动器程序与集群管 ...
- 【BZOJ 3926】【ZJOI 2015】诸神眷顾的幻想乡
http://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机的例题,感觉广义后缀自动机好恶心... 广义后缀自动机是对一个trie建立的后缀 ...
- 关于bootstrap的modal弹出层嵌套子Modal所引发的血案(转)
原文地址 http://blog.csdn.net/liuxiaogangqq/article/details/51821359 bootstrap的弹出层嵌套有一个问题 ,当子modal关闭时父的m ...
- 选择移动web开发框架研究——有mui、frozenui以及Sencha Touch等
纯粹的总结一下移动web开发框架,移动 web开发框架有jQuery Mobile .Sencha Touch等等,他们都来源于web开发,是成熟的框架,jQuery Mobile出自于jQuery家 ...
- Linux释放内存脚本
vi recover_mem.sh #!/bin/bash ################## #author:rrhelei@126.com# ################## #系统分配的 ...
- Iframe 自适应高度并实时监控高度变化的js代码
不得不用到iframe,且被强烈要求不能让它出现滚动条!嵌入的页面肯定是高度不一的,页面中也不能出现大片空白,所以也不能写死高度!真是麻鬼烦啊!google N次 + 百度M次 + 试验了1605次之 ...
- 使用 GitHub, Jekyll 打造自己的免费独立博客
使用 GitHub, Jekyll 打造自己的免费独立博客 GitHub是一个代码托管网站,现在很多开源项目都放在GitHub上. 利用GitHub,可以让全球各地的程序员们一起协作开发.GitHub ...
- jQ小图标上下滑动特效
嗯,又到了,夜静饥寒的时候,手指颤抖,回望去,屋内满是寂静,寥寥绰影,咳咳咳,想我程序员之路还没到终点...就...咳咳咳 好了日常神经结束,还要涂我的唇膏.还剩下,最后一章,js动画(四),明天放上 ...
- Bootstrap入门(三十)JS插件7:警告框
Bootstrap入门(三十)JS插件7:警告框 通过这个插件可以为警告信息添加点击以及消失的功能. 当使用一个.close按钮,它必须是第一个子元素.alert-dismissible,并没有文字内 ...
- JavaScript中DOM的层次节点(一)
DOM是针对HTML和XML文档的一个API,描绘了一个层次化的节点树,允许开发人员添加.修改.删除节点的一部分. DOM将HTML和XML文档描绘成一个有多个节点构成的结构,节点分为12种不同的节点 ...