1. 1 #include <cstdio>
  2. 2 #include <queue>
  3. 3 #include <set>
  4. 4 #include <cstring>
  5. 5 #include <string>
  6. 6 #define N 205
  7. 7 using namespace std;
  8. 8 int r, c, k;
  9. 9 char mp[N][N]; //地图位置
  10. 10 int tag[N][N]; //标志位,判断是否重复走
  11. 11 int door[N*N][2] = {}; //传送门位置
  12. 12 int door_cnt = 0; //有多少道传送门
  13. 13 int sx, sy, ex, ey; //起点和终点
  14. 14 int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; //方向
  15. 15 typedef struct Node{ //每一个状态的结构体
  16. 16 int x, y, step; //位置和步数
  17. 17 //set<int> s; //开始是使用set保存宝石种类,发现0 > -1 为假,遂改为复杂形态
  18. 18 int ecnt; //宝石数量
  19. 19 bool e[5] = {}; //5种宝石是否被发现
  20. 20 Node(int x, int y, int step, int ecnt):x(x), y(y), step(step), ecnt(ecnt){}; //构造函数
  21. 21 }node;
  22. 22
  23. 23 bool judge(node nx){ //判断是否往下走
  24. 24 if(nx.x >= 0 && nx.x < r && nx.y >= 0 && nx.y < c && mp[nx.x][nx.y] != '#' &&
  25. 25 nx.ecnt > tag[nx.x][nx.y]){
  26. 26 return true;
  27. 27 }
  28. 28 return false;
  29. 29 }
  30. 30 int bfs(){
  31. 31 node cur(sx, sy, 0, 0), next(sx, sy, 0, 0); //当前状态和下一下状态
  32. 32 queue<node> q; //队列
  33. 33 q.push(cur);
  34. 34 while(!q.empty()){
  35. 35 cur = q.front();
  36. 36 q.pop();
  37. 37 if(cur.x == ex && cur.y == ey && cur.ecnt >= k){ //满足结束条件,返回
  38. 38 //printf("%d ", cur.s.size());
  39. 39 return cur.step;
  40. 40 }
  41. 41 //printf("%d %d %d %d\n", cur.x, cur.y, cur.ecnt, cur.step);
  42. 42 //getchar();
  43. 43 for(int i = 0; i < 4; i++){ //上下左右试探
  44. 44 next.x = cur.x + dir[i][0];
  45. 45 next.y = cur.y + dir[i][1];
  46. 46 next.step = cur.step + 1;
  47. 47 next.ecnt = cur.ecnt;
  48. 48 memcpy(next.e, cur.e, 5); //计算下一步的所有数据
  49. 49 //printf("tag:%d %d %d\n", next.ecnt > tag[next.x][next.y], next.ecnt, tag[next.x][next.y]);
  50. 50 if(judge(next)){ //判断是否可以继续往下走
  51. 51 tag[next.x][next.y] = next.ecnt;
  52. 52 if(isdigit(mp[next.x][next.y])){ //是否是宝石
  53. 53 int e_cnt = 0;
  54. 54 next.e[mp[next.x][next.y]-48] = true;
  55. 55 for(int j = 0; j < 5; j++){
  56. 56 if(next.e[j]){
  57. 57 e_cnt++;
  58. 58 }
  59. 59 }
  60. 60 next.ecnt = e_cnt;
  61. 61 q.push(next);
  62. 62 }else if(mp[next.x][next.y] == '$'){ //是否是传送门
  63. 63 for(int j = 0; j < door_cnt; j++){
  64. 64 next.x = door[j][0];
  65. 65 next.y = door[j][1];
  66. 66 q.push(next);
  67. 67 }
  68. 68 }else if(mp[next.x][next.y] == 'E' || mp[next.x][next.y] == '.'){//正常道路
  69. 69 q.push(next);
  70. 70 }
  71. 71 }
  72. 72 }
  73. 73 }
  74. 74 return -1;
  75. 75 }
  76. 76 int main(){
  77. 77 int t;
  78. 78 scanf("%d", &t);
  79. 79 while(t--){
  80. 80 memset(tag, -1, sizeof(tag)); //初始化标志位
  81. 81 memset(mp, 0, sizeof(mp)); //初始化地图
  82. 82 door_cnt = 0; //传送门初始化
  83. 83 scanf("%d %d %d", &r, &c, &k); //地图大小和需要的宝石种类
  84. 84 getchar();
  85. 85 for(int i = 0; i < r; i++){ //记录初始位置,结束位置和所有传送门
  86. 86 scanf("%s", mp[i]);
  87. 87 for(int j = 0; j < c; j++){
  88. 88 switch(mp[i][j]){
  89. 89 case 'S':
  90. 90 sx = i;
  91. 91 sy = j;
  92. 92 break;
  93. 93 case 'E':
  94. 94 ex = i;
  95. 95 ey = j;
  96. 96 break;
  97. 97 case '$':
  98. 98 door[door_cnt][0] = i;
  99. 99 door[door_cnt][1] = j;
  100. 100 door_cnt++;
  101. 101 break;
  102. 102 }
  103. 103 }
  104. 104 }
  105. 105 int cnt = bfs(); // bfs暴搜
  106. 106 if(cnt == -1){
  107. 107 printf("oop!");
  108. 108 }else{
  109. 109 printf("%d\n", cnt);
  110. 110 }
  111. 111 }
  112. 112 return 0;
  113. 113 }

T1215拯救公主的更多相关文章

  1. noi 7221 拯救公主 (状态压缩+bfs)

    /* 这题实在调糊了 借鉴的题解的一些判断方法 位运算大法好 - - 因为要集齐所有的宝石所以状态压缩一下 f[i][j][s]将s化为二进制 每一0表示该宝石没有 1表示该宝石有 有:到(i,j)这 ...

  2. c++小游戏——拯救公主

    #include<stdio.h> #include<ctime> #include<time.h> //suiji #include<windows.h&g ...

  3. T1215:迷宫

    [题目描述] 一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行.同时当Extense处在某 ...

  4. openjudge 拯救公主

    点击打开题目 看到这道题,第一感觉是我有一句m2p不知当讲不当讲 传送门就算了,你提莫还来宝石,还不给我每种最多有几个~~ 在一般的迷宫问题里,无论已经走了多少步,只要到达同一个点,状态便是等价的,但 ...

  5. 【STL】优先队列priority_queue详解+OpenJudge-4980拯救行动

    一.关于优先队列 队列(queue)这种东西广大OIer应该都不陌生,或者说,队列都不会你还学个卵啊(╯‵□′)╯︵┻━┻咳咳,通俗讲,队列是一种只允许从前端(队头)删除元素.从后端(队尾)插入元素的 ...

  6. OpenJudge4980:拯救行动//stl优先队列

    总时间限制:  10000ms 内存限制:  65536kB 描述 公主被恶人抓走,被关押在牢房的某个地方.牢房用N*M (N, M <= 200)的矩阵来表示.矩阵中的每项可以代表道路(@). ...

  7. hdu 2102 A计划-bfs

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  8. bzoj3007: 拯救小云公主

    Description     英雄又即将踏上拯救公主的道路……     这次的拯救目标是——爱和正义的小云公主.     英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是 ...

  9. hdu 2102 A计划

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2102 A计划 Description 可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸 ...

随机推荐

  1. jenkins:实现Jenkinsfile与Json的转换

    实现Jenkinsfile与Json的转换 目录 实现Jenkinsfile与Json的转换 方法1:使用现有的jenkins插件 参考 方法2:解析原生的jenkinsfile文件 参考 最近在做个 ...

  2. ElasticSearch 交互使用

    Curl 命令 # 建立索引 [root@dbtest01 ~]# curl -XPUT 'http://10.0.0.121:9200/test' # 插入数据 [root@dbtest01 ~]# ...

  3. 【非原创】codeforces - 1067A Array Without Local Maximums【dp】

    学习博客:戳这里 附本人代码: 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 co ...

  4. how to updating Node.js and npm

    how to updating  Node.js and npm 1 Installing Node.js and updating npm How do I update Node.js ? Not ...

  5. 微信小程序-云开发-实战项目

    微信小程序-云开发-实战项目 微信小程序 微信小程序平台服务条款 https://developers.weixin.qq.com/miniprogram/product/service.html h ...

  6. 如何用 js 实现一个类似微信红包的随机算法

    如何用 js 实现一个类似微信红包的随机算法 js, 微信红包, 随机算法 "use strict"; /** * * @author xgqfrms * @license MIT ...

  7. WebXR All in One

    WebXR All in One VR / WebVR WebXR https://www.w3.org/TR/webxr/ WebXR Device API https://immersiveweb ...

  8. convert number or string to ASCII in js

    convert number or string to ASCII in js ASCII dictionary generator // const dict = `abcdefghijklmnop ...

  9. how to make one your own promise version Ajax

    how to make one your own promise version Ajax XMLHttpRequest https://developer.mozilla.org/en-US/doc ...

  10. AMP ⚡

    AMP https://amp.dev/zh_cn/ PWA AMP Playground https://playground.amp.dev/?runtime=amp4email <!doc ...