[ZJOI2005]九数码游戏

题目描述

输入输出格式

输入格式:

输入文件中包含三行三列九个数,同行的相邻两数用空格隔开,表示初始状态每个方格上的数字。初始状态不会是目标状态。

输出格式:

如果目标状态无法达到,则输出“UNSOLVABLE”(引号不输出)。

否则,第一行是一个整数S,表示最少的操作次数。接下来4 × (S + 1)行,每四行表示一个状态:前三行每行三个整数,相邻两数用空格隔开,表示每个方格上的数字,第四行是一个空行,作为分隔。第一个状态必须是初始状态,最后一个状态必须是目标状态。

输入输出样例

输入样例#1:

  1. 2 3 0
  2. 1 8 7
  3. 5 4 6
输出样例#1:

  1. 4
  2. 2 3 0
  3. 1 8 7
  4. 5 4 6
  5.  
  6. 1 2 3
  7. 5 8 0
  8. 4 6 7
  9.  
  10. 1 2 3
  11. 0 5 8
  12. 4 6 7
  13.  
  14. 0 1 2
  15. 4 5 3
  16. 6 7 8
  17.  
  18. 0 1 2
  19. 3 4 5
  20. 6 7 8
  21.  
  22. 因为这是3*3的全排列矩阵变换;
    最多有9!(362880)种状态;
    BFS,搜到终点为止,中间记录一下路径;
    3*3的全排列映射成一一对应的数,可以用康托展开;
    最好不要用map,可能会超时;
  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<map>
  6. using namespace std;
  7.  
  8. int a[],q[],st,ed,b[],f[],ge,ans;
  9. int c[],hash[];
  10. int fac[]={,,,,,,,,};
  11.  
  12. int calc1()
  13. {
  14. int i,j,t,sum;
  15. sum=;
  16. for(i=;i<;i++)
  17. {
  18. t=;
  19. for(j=i+;j<;j++)
  20. if(a[i]>a[j])
  21. ++t;
  22. sum+=t*fac[-i-];
  23. }
  24. return sum+;
  25. }
  26.  
  27. int calc()
  28. {
  29. int i,j,t,sum;
  30. sum=;
  31. for(i=;i<;i++)
  32. {
  33. t=;
  34. for(j=i+;j<;j++)
  35. if(b[i]>b[j])
  36. ++t;
  37. sum+=t*fac[-i-];
  38. }
  39. return sum+;
  40. }
  41.  
  42. void fen(int x)
  43. {
  44. int i,j,t,vst[]={};
  45. x--;
  46. for(i=;i<;i++)
  47. {
  48. t=x/fac[-i-];
  49. for(j=;j<;j++)
  50. if(!vst[j])
  51. {
  52. if(t==) break;
  53. --t;
  54. }
  55. b[i]=j;
  56. vst[j]=;
  57. x%=fac[-i-];
  58. }
  59. }
  60.  
  61. int main()
  62. {
  63. int x=;
  64. for(int i=;i<=;i++)
  65. for(int j=;j<=;j++){
  66. scanf("%d",&a[(i-)*+j-]);
  67. }
  68. x=calc1();
  69. ge=;
  70. if(x==ge){
  71. printf("");
  72. return ;
  73. }
  74. q[]=x;
  75. hash[x]=-;
  76. st=; ed=;
  77. while(st<ed){
  78. int x=q[++st];
  79. fen(x);
  80. for(int i=;i<;i++)
  81. f[i]=b[i];
  82. b[]=f[];
  83. b[]=f[];
  84. b[]=f[];
  85. int y=calc();
  86. if(hash[y]==){
  87. hash[y]=x;
  88. ed++;
  89. q[ed]=y;
  90. }
  91. if(y==ge)
  92. break;
  93. b[]=f[];
  94. b[]=f[];
  95. b[]=f[];
  96.  
  97. b[]=f[];
  98. b[]=f[];
  99. b[]=f[];
  100. b[]=f[];
  101. b[]=f[];
  102. b[]=f[];
  103. b[]=f[];
  104. b[]=f[];
  105.  
  106. y=calc();
  107. if(hash[y]==){
  108. hash[y]=x;
  109. ed++;
  110. q[ed]=y;
  111. }
  112. if(y==ge)
  113. break;
  114. }
  115. x=hash[ge];
  116. if(x==){
  117. printf("UNSOLVABLE\n");
  118. return ;
  119. }
  120. while(x!=-){
  121. ans++;
  122. c[ans]=x;
  123. x=hash[x];
  124. }
  125. printf("%d\n",ans);
  126. for(int i=ans;i>;i--){
  127. fen(c[i]);
  128. printf("%d %d %d\n",b[],b[],b[]);
  129. printf("%d %d %d\n",b[],b[],b[]);
  130. printf("%d %d %d\n",b[],b[],b[]);
  131. printf("\n");
  132. }
  133. if(ans>=){
  134. printf("0 1 2\n");
  135. printf("3 4 5\n");
  136. printf("6 7 8\n");
  137. }
  138. }
  1.  

[ZJOI2005]九数码游戏的更多相关文章

  1. [ZJOI2005]九数码游戏(BFS+hash)

    Solution 这题的话直接上BFS就可以了,因为要输出方案,所以我们要开一个pre数组记录前驱,最后输出就可以了. 对于状态的记录,一般都用哈希来存,但因为这道题比较特殊,它是一个排列,所以我们可 ...

  2. 洛谷 P2578 [ZJOI2005]九数码游戏【bfs+康托展开】

    只有9!=362880个状态,用康托展开hash一下直接bfs即可 #include<iostream> #include<cstdio> #include<cstrin ...

  3. 万圣节后的早晨&&九数码游戏——双向广搜

    https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...

  4. LG2578 「ZJOI2005」九数码游戏 bfs

    问题描述 LG2578 题解 用string+map去重. bfs即可. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace ...

  5. 洛谷 - P2578 - 九数码游戏 - bfs

    https://www.luogu.org/problemnew/show/P2578 一个挺搞的东西,用康托展开做记忆化搜索可以少一个log的查询. #include <bits/stdc++ ...

  6. C#_界面程序_数码游戏

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. ZJOI2017 Day1

    私のZJOI Day1 2017-3-21 07:52:53 有人在暴力膜 苟-- 富贵 无相忘 ZJOI2017交流群 133135071 如果你足够厉害 如果你足够厉害 如果你足够厉害 其实完全可 ...

  8. [学习笔记]搜索——模拟与dp的结合

    搜索: 一种基础的算法. 考察常见于NOIP 但是高级的搜索算法可能还会在省选出现. 50%以上的暴力都可以用搜索直接枚举来写. 但是,当数据规模不是很大的时候,搜索也可能成为正解. (比如剪枝PK状 ...

  9. HDU 1043 Eight 八数码问题 A*算法(经典问题)

    HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...

随机推荐

  1. 转:js闭包

    一切都是对象 "一切都是对象"这句话的重点在于如何去理解"对象"这个概念. --当然,也不是所有的都是对象,值类型就不是对象. 首先咱们还是先看看javascr ...

  2. 8个超震撼的HTML5和纯CSS3动画源码

    HTML5和CSS3之所以强大,不仅因为现在大量的浏览器的支持,更是因为它们已经越来越能满足现代开发的需要.Flash在几年之后肯定会消亡,那么HTML5和CSS3将会替代Flash.今天我们要给大家 ...

  3. Git与码云(Git@OSC)入门-如何在实验室和宿舍同步你的代码(1)

    0.几个基本概念 本地仓库:本机上某个存放代码的仓库. 远程仓库:码云服务器上的代码仓库. 重要提醒:当我们在本地操作(新增.删除.修改)文件.目录时,并将其提交(commit),就是提交到了本地仓库 ...

  4. 201521123080《Java程序设计》第14周学习总结

    本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 书面作业 MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) ...

  5. 201521123050 《Java程序设计》第9周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避 ...

  6. 参考:Python 调试方法

    地址:http://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/ 这是Python代码调试技巧,也是我今天从别的地方看到的,然后转载 ...

  7. Mybatis第八篇【一级缓存、二级缓存、与ehcache整合】

    Mybatis缓存 缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题. myba ...

  8. Windows下chm转换为html的超简单方法

    摘要:通过调用Windows命令,将chm 文件转换为html 文件 概述:很多程序员朋友都会遇到这样的问题,看一个离线版的帮助文档(chm文件),总会产生一个索引文件(该文件的chw文件), 而且有 ...

  9. vue源码学习-vnode的挂载和更新流程

    概述 本文主要介绍在视图的渲染过程中,Vue 是如何把 vnode 解析并挂载到页面中的.我们通过一个最简单的例子来分析主要流程: <div id="app"> {{s ...

  10. javascript插入before(),after()新DOM方法

    随着web的技术突飞猛进的发展.HTML5 ES6等新技术的发展,与此同时DOM等标准也在悄悄的进步,各大浏览器也在悄悄的发展适配新的属性和方法,今天我们来看看Javascript新的DOM的方法 二 ...