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分别表示.任一时刻魔板的状态可 ...
随机推荐
- java 容器、二叉树操作、107
二叉树本身固有的递归性质,通常可以用递归算法解决,虽然递归代码简介,但是性能不如非递归算法. 常用的操作是构建二叉树.遍历二叉树(先序.中序.后序.都属于DFS深度优先搜索算法,使用栈来实现),广度优 ...
- Bzoj3756
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3756 题解:乱搞 代码: #include<iostream> #include ...
- 最简化模型——css3分阶段动画效果(经过实测)
body { background: #dcdcdc; -webkit-animation: colorin 5s; /* chrome调用属性 */ animation: colo ...
- delphi TServerSocket的多线程
http://blog.sina.com.cn/s/blog_471218c2010001qc.html unit U_dxc; interface uses Windows, Messages, ...
- Linux下修改键盘映射
一篇关于修改键盘映射比较靠谱的文章,收藏一下! 原文地址:http://www.07net01.com/2016/04/1436249.html --------------------------- ...
- Strut、Spring、Hibernate如何实现资源整合(SSH)呢?
Strut.Spring.Hibernate如何实现资源整合(SSH)呢? 其实很简单,我们从Spring与Hibernate的整合中可以看出来,由Spring的配置文件来管理Hiberbate的配置 ...
- Java Me-List控件的用法案例
/** * Java Me-List控件的用法案例 */package com.xushouwei.cn; import java.io.IOException;import javax.microe ...
- MyBatis 一对多关联查询
sqlxml文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC ...
- SSM框架整合(注解)-Spring+SpringMVC+MyBatis+MySql
准备工作: 下载整合所需的jar包 点击此处下载 使用MyBatis Generator生成dao接口.映射文件和实体类 如何生成 搭建过程: 先来看一下项目的 目录结构 1.配置dispatcher ...
- 关于redis的主从、哨兵、集群
关于redis主从.哨兵.集群的介绍网上很多,这里就不赘述了. 一.主从 通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失)数据,因为持久化会把内存中数据保存到硬盘上,重 ...