松下问童子,言师采药去。

只在此山中,云深不知处。——贾岛

题目:魔板 Magic Squares

网址:https://www.luogu.com.cn/problem/P2730

这是一张有8个大小相同的格子的魔板:

1 2 3 4

8 7 6 5

题目描述

我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。

对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示。

这是基本状态。

这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改变魔板的状态):

“A”:交换上下两行;

“B”:将最右边的一列插入最左边;

“C”:魔板中央四格作顺时针旋转。

下面是对基本状态进行操作的示范:

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

对于每种可能的状态,这三种基本操作都可以使用。

你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。

输入格式

只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。

输出格式

Line 1: 包括一个整数,表示最短操作序列的长度。

Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。

输入样例
  1. 2 6 8 4 5 7 3 1
输出样例
  1. 7
  2. BCABCCB
说明

选自USACO Training Section 3.2

做完八数码问题,不难理解这道题可以使用广搜解决(毕竟时间复杂度与八数码问题类似)。

像之前的八数码问题一样,我们把状态定义成一个八位数,代码中简单的使用STL中map和set进行记录与判重。

留意:本题有一个陷肼,如果使用从上到下、从左向右进行加和操作确定状态时,初状态应为:12348765!

代码如下:

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<queue>
  6. #include<map>
  7. #include<set>
  8. using namespace std;
  9. const int rot[4] = {2, 1, 5, 6};
  10. int st = 12348765, ed = 0, s[10];
  11. map <int, int> d, f;
  12. set <int> vis;
  13. void decode(int state, int *p)
  14. {
  15. for(int i = 7; i >= 0; -- i)
  16. {
  17. p[i] = state % 10;
  18. state /= 10;
  19. }
  20. //将十进制编码转化为数组
  21. return;
  22. }
  23. int encode(int *p)
  24. {
  25. int cnt = 0;
  26. for(int i = 0; i < 8; ++ i)
  27. {
  28. cnt = (cnt << 1) + (cnt << 3) + p[i];
  29. }
  30. //将数组转化为十进制8位编码
  31. return cnt;
  32. }
  33. void flip(int cur, int *p)
  34. {
  35. switch(cur)
  36. {
  37. case 0 :
  38. {
  39. for(int i = 0; i < 4; ++ i)
  40. {
  41. swap(p[i], p[i + 4]);
  42. }
  43. break;
  44. }
  45. case 1 :
  46. {
  47. for(int i = 2; i > -1; -- i)
  48. {
  49. swap(p[i], p[i + 1]);
  50. swap(p[i + 4], p[i + 5]);
  51. }
  52. break;
  53. }
  54. case 2 :
  55. {
  56. for(int i = 0; i < 3; ++ i)
  57. {
  58. swap(p[rot[i]], p[rot[i + 1]]);
  59. }
  60. break;
  61. }
  62. }
  63. return;
  64. }
  65. void print_ans(int state)
  66. {
  67. if(state == st) return;
  68. int prev_state = 0;
  69. decode(state, s);
  70. switch(f[state])
  71. {
  72. case 0:
  73. {
  74. for(int i = 0; i < 4; ++ i)
  75. {
  76. swap(s[i], s[i + 4]);
  77. }
  78. break;
  79. }
  80. case 1:
  81. {
  82. for(int i = 0; i < 3; ++ i)
  83. {
  84. swap(s[i], s[i + 1]);
  85. swap(s[i + 4], s[i + 5]);
  86. }
  87. break;
  88. }
  89. case 2:
  90. {
  91. for(int i = 2; i >= 0; -- i)
  92. {
  93. swap(s[rot[i + 1]], s[rot[i]]);
  94. }
  95. break;
  96. }
  97. }
  98. for(int i = 0; i < 8; ++ i)
  99. {
  100. prev_state = prev_state * 10 + s[i];
  101. }
  102. memset(s, 0, sizeof(s));
  103. print_ans(prev_state);
  104. printf("%c", f[state] + 'A');
  105. return;
  106. }
  107. void bfs()
  108. {
  109. //特判 初始状态 和 目标状态 相同
  110. if(st == ed) {
  111. puts("0");
  112. return;
  113. }
  114. f.clear(), vis.clear();
  115. queue <int> Q;
  116. while(!Q.empty()) Q.pop();
  117. Q.push(st);
  118. vis.insert(st);
  119. int copy[8] = {}, now, next;
  120. while(!Q.empty())
  121. {
  122. now = Q.front();
  123. Q.pop();
  124. decode(now, s);
  125. memcpy(copy, s, sizeof(copy));
  126. for(int i = 0; i < 3; ++ i)
  127. {
  128. flip(i, s);
  129. next = encode(s);
  130. memcpy(s, copy, sizeof(s));
  131. if(vis.count(next)) continue;
  132. d[next] = d[now] + 1;
  133. f[next] = i;
  134. if(next == ed)
  135. {
  136. printf("%d\n", d[next]);
  137. print_ans(next);
  138. return;
  139. }
  140. Q.push(next);
  141. vis.insert(next);
  142. }
  143. }
  144. return;
  145. }
  146. int main()
  147. {
  148. memset(s, 0, sizeof(s));
  149. for(int i = 0; i < 4; ++ i) scanf("%d", &s[i]);
  150. //目标状态处理:
  151. for(int i = 7; i >= 4; -- i) scanf("%d", &s[i]);
  152. //留意陷阱呢
  153. for(int i = 0; i < 8; ++ i)
  154. {
  155. ed = (ed << 1) + (ed << 3) + s[i];
  156. }
  157. bfs();
  158. return 0;
  159. }

[USACO3.2]魔板 Magic Squares的更多相关文章

  1. 「一本通 1.4 例 2」[USACO3.2]魔板 Magic Squares

    [USACO3.2]魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题 ...

  2. 洛谷 P2730 魔板 Magic Squares 解题报告

    P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 ...

  3. 哈希+Bfs【P2730】 魔板 Magic Squares

    没看过题的童鞋请去看一下题-->P2730 魔板 Magic Squares 不了解康托展开的请来这里-->我这里 至于这题为什么可以用康托展开?(瞎说时间到. 因为只有8个数字,且只有1 ...

  4. 【简●解】 LG P2730 【魔板 Magic Squares】

    LG P2730 [魔板 Magic Squares] [题目背景] 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 ...

  5. 洛谷 P2730 魔板 Magic Squares

    P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 ...

  6. [洛谷P2730] 魔板 Magic Squares

    洛谷题目链接:魔板 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都 ...

  7. 魔板 Magic Squares(广搜,状态转化)

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

  8. P2730 魔板 Magic Squares

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

  9. 洛谷P2730 [IOI]魔板 Magic Squares

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

随机推荐

  1. java单元/集成测试中使用Testcontainers

    1.Testcontainers介绍: Testcontainers是一个Java库,它支持JUnit测试,提供公共数据库.SeleniumWeb浏览器或任何可以在Docker容器中运行的轻量级.一次 ...

  2. TCP漫谈之keepalive和time_wait

    TCP是一个有状态通讯协议,所谓的有状态是指通信过程中通信的双方各自维护连接的状态. 一.TCP keepalive 先简单回顾一下TCP连接建立和断开的整个过程.(这里主要考虑主流程,关于丢包.拥塞 ...

  3. IDEA+Mybatis-generator代码生成工具

    IDEA+Mybatis-generator代码生成工具(小白也能用) 插件介绍 MyBatis Generator简称MBG,是MyBatis 官方出的代码生成器.MBG能够自动生成实体类.Mapp ...

  4. 《Three.js 入门指南》3.1.1 - 基本几何形状 - 平面(PlaneGeometry)

    3.1 基本几何形状 平面(PlaneGeometry) 说明: 这里的平面(PlaneGeometry)其实是一个长方形,而不是数学意义上无限大小的平面. 构造函数: THREE.PlaneGeom ...

  5. IIS 组成

    HTTP.sys      http.sys 侦听来自网络的 HTTP 请求,将它们传递到 IIS 并返回响应. 它是一种可以从命令行停止和启动的服务.      "NET STOP HTT ...

  6. Shell:Day08.笔记

    函数:写一个代码块,用来重复调用的: 1.函数的写法格式 2.参数,在函数名后面直接加,即可:如果在外面  abc(){   函数体 $@  }  abc 1 2 3 4 5   :wq    a.s ...

  7. spring官方为什么放弃spring social项目及替代方案

    spring social 1.6之后官方不在维护该项目, spring boot 2.x之后也不在提供spring social的 Autoconfiguration. 原因: https://sp ...

  8. WireShark数据包分析一:认识WireShark

    一.认识WireShark WireShark是一款抓包软件,官方网址:WireShark.org 官网如下图: 选择Download,在官网下载安装WireShark即可. WireShark可用来 ...

  9. linux中的隐藏权限,chattr,lsattr

    chattr chattr可以用来制约root的权限,使得系统更加安全. 主要参数: a:让文件或目录仅供附加用途. b:不更新文件或目录的最后存取时间. c:将文件或目录压缩后存放. d:将文件或目 ...

  10. 一个有关 scala 编程语言 的博客

    http://www.cnblogs.com/superjt/category/312683.html