最近昀昀学习到了一种新的棋盘游戏,这是一个在一个N×N的格子棋盘上去搞M个棋子的游戏,游戏的规则有下列几条:

  1. 棋盘上有且仅有一个出口
  2. 开始时没有哪个棋子在出口,而且所有棋子都不相邻(这里的相邻是指上下左右四个方向)
  3. M个棋子分别记为1到M
  4. 每个时刻你可以移动一个棋子向它相邻的四个格子移动一步
  5. 你需要保证任意时刻棋盘上所有棋子都不相邻
  6. 只有当前棋盘上编号最小的棋子移动到出口时才能取走改棋子。
  7. 所有棋子都移走的时候游戏结束

对于一个给定的游戏局面,昀昀最少要多少步才能结束这个游戏呢?

Input

第一行有一个整数T,(T≤200),表示测试数据的组数。

对于每一组数据,第一行是两个整数N,M,其中2≤N≤6, 1≤M≤4。

接下来是一个N×N的棋盘,其中o代表空格子,x代表出口,其余的1到M代表这M个棋子。

保证数据是合法的。

Output

对于每一组数据输出最少步数,如果无解输出−1。

Sample input and output

Sample Input Sample Output
  1. 2
  2. 3 2
  3. x2o
  4. ooo
  5. oo1
  6.  
  7. 3 3
  8. xo1
  9. o2o
  10. 3oo
  1. 7
  2. -1

解题报告

自己也是太年轻。。以为是道大水题,直接上bfs爆搜,果断TLE。。

略思考后显然是A*算法(大水题。。。曼哈顿距离呐)

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <queue>
  7.  
  8. using namespace std;
  9.  
  10. const int Max= ;
  11. int N,M,tid,ttx,tty;
  12. char G[Max][Max];
  13. bool vis[][][][];
  14.  
  15. typedef struct status{
  16. int pos[],step,pol,f;
  17. friend bool operator < (status a,status b)
  18. {
  19. if (a.step + a.f < b.step + b.f) return false;
  20. if (a.step + a.f > b.step + b.f) return true;
  21. if (a.step < b.step) return false;
  22. else
  23. return true;
  24. }
  25. };
  26.  
  27. priority_queue<status>q;
  28. status start;
  29. int pol;
  30. int dir[][] = {,,,-,,,-,};
  31.  
  32. /*A* */
  33. int caculatef(status& x){
  34. int result = ;
  35. for(int i = ;i<M;++i)
  36. result += (abs(x.pos[i] / N - ttx) + abs(x.pos[i] % N - tty) );
  37. return result;
  38. }
  39.  
  40. bool judge(status &x){
  41. for(int i = x.pol;i < M;++i)
  42. for(int j = i;j < M;++j)
  43. if (i != j)
  44. {
  45. int tx1 = x.pos[i] / N;
  46. int ty1 = x.pos[i] % N;
  47. int tx2 = x.pos[j] / N;
  48. int ty2 = x.pos[j] % N;
  49. if (tx1 == tx2 && abs(ty1 - ty2) == ) return false;
  50. else if(ty1 == ty2 && abs(tx1-tx2) == ) return false;
  51. else if(tx1 == tx2 && ty1 == ty2) return false;
  52. }
  53. return true;
  54. }
  55.  
  56. int bfs(){
  57. memset(vis,false,sizeof(vis));
  58. vis[start.pos[]][start.pos[]][start.pos[]][start.pos[]] = true;
  59. start.step = ;
  60. q.push(start);
  61. while(!q.empty())
  62. {
  63. status temp = q.top();q.pop();
  64. if(temp.pos[temp.pol] == tid)
  65. temp.pol++;
  66. if (temp.pol == M) return temp.step;
  67. for(int i = temp.pol;i<M;++i)
  68. for(int j = ;j<;++j)
  69. {
  70. int newx = temp.pos[i] / N + dir[j][];
  71. int newy = temp.pos[i] % N + dir[j][];
  72. if (newx >= N || newx < || newy >= N || newy < ) continue;
  73. int nid = newx * N + newy;
  74. status nst = temp;
  75. nst.pos[i] = nid;
  76. if (!judge(nst)) continue;
  77. if (vis[nst.pos[]][nst.pos[]][nst.pos[]][nst.pos[]] ) continue;
  78. vis[nst.pos[]][nst.pos[]][nst.pos[]][nst.pos[]] = true;
  79. nst.step = temp.step + ;
  80. nst.f = caculatef(nst);
  81. q.push(nst);
  82. }
  83. }
  84.  
  85. return -;
  86. }
  87.  
  88. int main(int argc,char * argv[]){
  89. int T;
  90. scanf("%d",&T);
  91. while(T--)
  92. {
  93. while(!q.empty())
  94. q.pop();
  95. for(int i = ;i<;++i)
  96. start.pos[i] = ;
  97. start.pol = ;
  98. scanf("%d%d%*c",&N,&M);
  99. for(int i = ;i<N;++i)
  100. gets(G[i]);
  101. for(int i = ;i<N;++i)
  102. for(int j = ;j<N;++j)
  103. if(G[i][j] <= '' && G[i][j] >='')
  104. start.pos[G[i][j] - ''] = i*N+j;
  105. else if(G[i][j] == 'x')
  106. tid = i*N + j;
  107. ttx = tid / N;
  108. tty = tid % N;
  109. start.f = caculatef(start);
  110. cout << bfs() << endl;
  111. }
  112. return ;
  113. }

UESTC_棋盘游戏 CDOJ 578的更多相关文章

  1. UESTC_握手 CDOJ 913

    握手 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status ...

  2. UESTC_冰雪奇缘 CDOJ 843

    艾莎女王又开始用冰雪魔法盖宫殿了. 她决定先造一堵墙,于是释放魔法让形为直角梯形的冰砖从天而降,定入冻土之中. 现在你将回答女王的询问:某段冻土上冰砖的面积. 注:多块冰砖之间会互相重叠,重叠部分要多 ...

  3. UESTC_敢说就敢做 CDOJ 631

    敢说就敢做 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  4. UESTC_方老师的分身 II CDOJ 915

    方老师的分身 II Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  5. UESTC_方老师分身 I CDOJ 914

    方老师分身 I Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit S ...

  6. UESTC_神秘绑架案 CDOJ 881

    神秘绑架案 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  7. UESTC_方老师买表 CDOJ 885

    老师买表 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Stat ...

  8. UESTC_冬马党 CDOJ 882

    冬马党 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Statu ...

  9. UESTC_魔法少女小蟹 CDOJ 710

    小蟹是一名魔法少女,能熟练的施放很多魔法. 有一天魔法学院上课的时候出现了这样一道题,给一个6位数,让大家用自己的魔法,把这个6位数变成另一个给定的6位数. 小蟹翻了下魔法书,发现她有以下6种魔法: ...

随机推荐

  1. 理解mcelog如何工作

    前言 本文,带你了解几个问题? 本文重点,主要看案例2,带你很好的理解mcelog如何工作的? mcelog的干什么的? mcelog 是 x86 的 Linux 系统上用来 检查硬件错误,特别是内存 ...

  2. 第11讲- Android中进程及其优先级

    第11讲Android中进程及其优先级 进程与线程: 进程:操作系统结构的基础,资源分配的最小单元,一个操作系统包括多个进程: 线程:线程存在于进程当中,是操作系统调试执行的最小单元,一个进程包括多个 ...

  3. hdu 5640 King's Cake(模拟)

    Problem Description   It is the king's birthday before the military parade . The ministers prepared ...

  4. python之路-模块 splinter

    Splinter介绍 Splinter is an open source tool for testing web applications using Python. It lets you au ...

  5. 海量路由表能够使用HASH表存储吗-HASH查找和TRIE树查找

    千万别! 非常多人这样说,也包括我. Linux内核早就把HASH路由表去掉了.如今就仅仅剩下TRIE了,只是我还是希望就这两种数据结构展开一些形而上的讨论. 1.hash和trie/radix ha ...

  6. CREATE PROCEDURE

    1 CREATE PROCEDURE(创建) CREATE PROCEDURE存储过程名(參数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的參数列必须总是存在.假设没有參数,也该使 ...

  7. css_day5

  8. html5 音频

    目前,web页面上没有标准的方式来播放音频文件,大多数的音频文件是使用插件来播放,而众多的浏览器使用了不同的插件.而html5的到来,给我们提供了一个标准的方式来播放web中音频文件,用户不再为浏览器 ...

  9. shell参数

    shell获取当前执行脚本的路径 filepath=$(cd "$(dirname "$0")"; pwd) 脚本文件的绝对路径存在了环境变量filepath中 ...

  10. 1203.3——循环语句 之 while

    while循环 while循环的一般形式为:    while(表达式){        语句块    }其中表达式称为循环条件,语句块称为循环体. while语句的意思是:先计算表达式的值,当值为真 ...