有一个  3×3 的平面魔方,在平面魔方中,每个格子里分别无重复地写上 1 - 9 这 9 个数字。一共有 4 种对平面魔方的操作:

  • 选择某一行左移。
  • 选择某一行右移。
  • 选择某一列上移。
  • 选择某一列下移。

初始状态为


123

456

789

比如选择第一行左移,魔方会变成下面这样

231

456

789

现在给出魔方的一个状态,问你能否将魔方复原成初始状态。如果可以,计算最少操作次数。

输入格式

输入三行,每行三个 1 到 9 之间的整数。

输出格式

如果能还原成初始状态,输出最小的操作次数,否则输出 -1。

样例输入


样例输出

 

将魔方的状态转为数字,然后再用结构体存储,去进行状态变换,然后就是用map来判重并存操作数

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int maxn=1e7+;
using namespace std; struct node
{
int a[][];
bool operator < (const node &ts) const //map需要
{
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
if(a[i][j]<ts.a[i][j])
return ;
}
}
return ;
}
bool operator == (const node &ts) const //用于出递归
{
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
if(a[i][j]!=ts.a[i][j])
return ;
}
}
return ;
}
void print()
{
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
printf(j==?"%d\n":"%d",a[i][j]);
}
}
}
int tonum()//返回一个代表魔方状态的int
{
int res=;
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
res=res*+a[i][j];
}
}
return res;
}
};
node last; node rotate(node u,int num,int op)//获取魔方的下一个状态
{
node res=u;
if(op==-)//右移
{
swap(res.a[num][],res.a[num][]);
swap(res.a[num][],res.a[num][]);
}
else if(op==)//左移
{
swap(res.a[num][],res.a[num][]);
swap(res.a[num][],res.a[num][]);
}
else if(op==-)//上移
{
swap(res.a[][num],res.a[][num]);
swap(res.a[][num],res.a[][num]);
}
else if(op==)//下移
{
swap(res.a[][num],res.a[][num]);
swap(res.a[][num],res.a[][num]);
}
return res;
} void BFS(node first)
{
queue<node> qe;
map<int,int> mp;//判断某一状态是否出现过,并且记录操作数
qe.push(first);
mp[first.tonum()]=;
while(!qe.empty())
{
node t=qe.front();
qe.pop();
int tt=t.tonum();
if(t==last)
{
printf("%d\n",mp[t.tonum()]);
return ;
}
node to;
for(int i=;i<=;i++)
{
to=rotate(t,i,-);
if(!mp.count(to.tonum()))
{
mp[to.tonum()]=mp[tt]+;
qe.push(to);
}
to=rotate(t,i,);
if(!mp.count(to.tonum()))
{
mp[to.tonum()]=mp[tt]+;
qe.push(to);
}
to=rotate(t,i,-);
if(!mp.count(to.tonum()))
{
mp[to.tonum()]=mp[tt]+;
qe.push(to);
}
to=rotate(t,i,);
if(!mp.count(to.tonum()))
{
mp[to.tonum()]=mp[tt]+;
qe.push(to);
}
}
}
printf("-1\n");//不能成功
} int main()
{
#ifdef DEBUG
freopen("sample.txt","r",stdin);
#endif for(int i=;i<=;i++)
{
for(int j=;j<=;j++)
{
last.a[i][j]=(i-)*+j;
}
}
node first;
for(int i=;i<=;i++)
{
int n;
scanf("%d",&n);
first.a[i][]=n%;
first.a[i][]=(n/)%;
first.a[i][]=n/;
}
BFS(first); return ;
}

-

三阶平面魔方(BFS)的更多相关文章

  1. 任意阶幻方(魔方矩阵)C语言实现

    魔方又称幻方.纵横图.九宫图,最早记录于我国古代的洛书.据说夏禹治水时,河南洛阳附近的大河里浮出了一只乌龟,背上有一个很奇怪的图形,古人认为是一种祥瑞,预示着洪水将被夏禹王彻底制服.后人称之为&quo ...

  2. magic矩阵 分类: 数学 2015-07-31 22:56 2人阅读 评论(0) 收藏

    魔方矩阵 魔方矩阵是有相同的行数和列数,并在每行每列.对角线上的和都相等.你能构造任何大小(除了2x2)的魔方矩阵. 1.历史       魔方又称幻方.纵横图.九宫图,最早记录于我国古代的洛书.据说 ...

  3. magic矩阵

    魔方矩阵 魔方矩阵是有相同的行数和列数,并在每行每列.对角线上的和都相等.你能构造任何大小(除了2x2)的魔方矩阵. 1.历史       魔方又称幻方.纵横图.九宫图,最早记录于我国古代的洛书.据说 ...

  4. ZJNU 1196 - 三阶魔方【模拟题】——高级

    大模拟,空想很容易把面和面之间的关系搞混 所以这时候需要自己找一个正方体(实在不行长方体代替)跟着图把每个面正方向标出来 然后模拟6种操作分别会对哪些块进行操作 对于储存数据的想法是,对输入输出进行分 ...

  5. 【ACM】魔方十一题

    0. 前言打了两年的百度之星,都没进决赛.我最大的感受就是还是太弱,总结起来就是:人弱就要多做题,人傻就要多做题.题目还是按照分类做可能效果比较好,因此,就有了做几个系列的计划.这是系列中的第一个,解 ...

  6. css3之3D魔方动画(小白版)

      在这里分享一下3D魔方动画,html5+CSS3即可完成~无图无真相,先上效果图 第一步非常简单,就是先将魔方的结构画出来.大家都玩过魔方,知道魔方是一个有六个面的正方体.这里我们先写一个大的di ...

  7. 程设大作业xjb写——魔方复原

    鸽了那么久总算期中过[爆]去[炸]了...该是时候写写大作业了 [总不能丢给他们不会写的来做吧 一.三阶魔方的几个基本定义 ↑就像这样,可以定义面的称呼:上U下D左L右R前F后B UD之间的叫E,LR ...

  8. EX的魔方

    https://www.luogu.org/problem/show?pid=2007 题目背景 常神牛从来没接触过魔方,所以他要借助计算机来玩.即使是这样,他还是很菜. 题目描述 常神牛家的魔方都是 ...

  9. 用DirectX实现魔方(一)

    关于魔方 魔方英文名字叫做Rubik's Cube,是由匈牙利建筑学教授和雕塑家Ernő Rubik于1974年发明,最初叫做Magic Cube(这大概也是中文名字的来历吧),1980年Ideal ...

随机推荐

  1. 查看linux硬件的信息

    cpu: cat  /proc/cpuinfo 内存: cat /proc/meminfo 查看内存使用情况: free -m     -m指以M的单位显示 查看硬盘使用情况: df -h       ...

  2. Apache服务器多站点配置

    Apache多站点设置,主要是关于httpd.conf配置文件的设置. 在httpd.conf配置文件中最后面的<VirtualHost>标签 #<VirtualHost *:80& ...

  3. spark任务日志配置

    样例代码: public class SparkTest { private static Logger logger = Logger.getLogger(SparkTest.class); pub ...

  4. yarn调度器 FairScheduler 与 CapacityScheduler

    yarn FairScheduler 与 CapacityScheduler CapacityScheduler(根据计算能力调度) CapacityScheduler 允许多个组织共享整个集群, 每 ...

  5. 区间DP----模板

    简介 区间dp,顾名思义就是在一段区间上进行动态规划.对于每段区间,他们的最优值都是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间问题不断划分为更小的区间直至一个元素组成的区间,枚举他们 ...

  6. Stuts2与SpringMVC

    Struts2:一个基于MVC设计模式的Web应用框架,本质上相当于一个servlet.以WebWork为核心,采用拦截器的机制处理用户的请求(Filter). 轻量级的MVC框架.低侵入性,与业务代 ...

  7. 【LeetCode】N皇后I

    [问题]n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案.每一种解法包含一个明确的 n 皇后问 ...

  8. php-fpm启动 关闭 重启

    http://www.cnblogs.com/GaZeon/p/5421906.html 最近安装了mysqli扩展,重启了nginx后,phpinfo()没有显示出mysqli,后来搞不出原因,直接 ...

  9. 201812-2 小明放学 Java

    思路: 红绿灯每种灯亮划分区间,在[0,r]区间内红灯亮,在(r,g+r]区间内绿灯亮,在(r+g,r+g+y]区间内黄灯亮,在划分好区间后只需要判断当小明到达红绿灯时是哪个灯在亮,就可以判断出通过红 ...

  10. 一文说透 Spring 循环依赖问题

    https://zhuanlan.zhihu.com/p/62382615 循环依赖发生的时机 Bean 实例化主要分为三步,如图: 问题出现在:第一步和第二步的过程中,也就是填充属性 / 方法的过程 ...