本题主要是存储的问题,在存储上笔者原先的代码占用了大量的内存空间

这边笔者采用暴力的思想直接硬开所有情况的16^6的数组来存储该问题,当然这在时间上是十分浪费的,因为初始化实在太慢了,剩下的就是状态转移,以及隐式图的相关思路

点击查看笔者代码
  1. #include<iostream>
  2. #include<cstring>
  3. #include<queue>
  4. #include<vector>
  5. using namespace std;
  6. constexpr int maxl = 16, maxn = 16777216+5, base = 4, debase = 15;
  7. int w, h, n, des, sta, st[maxl/4][2], ed[maxl/4][2], G[maxl][maxl];
  8. int dx[5] = {0, 0, 0, 1, -1};
  9. int dy[5] = {0, 1, -1, 0, 0};
  10. bool vis[maxn];
  11. struct Node{
  12. int value, costed;
  13. Node(int value = 0, int costed = 0) : value(value), costed(costed) {}
  14. };
  15. bool getD() {
  16. cin >> w >> h >> n;
  17. if(!w) return false;
  18. int cnt = 0, buf[26][2][2], sign[26]; memset(sign, 0, sizeof(sign));
  19. string line; getline(cin, line); memset(G, 1, sizeof(G));
  20. for(int i = 0; i < h; i++) {
  21. getline(cin, line);
  22. int len = line.length();
  23. for(int j = 0; j < len; j++) {
  24. if(line[j] == ' ') G[i][j] = 1;
  25. else if(line[j] == '#') G[i][j] = 0;
  26. else {
  27. G[i][j] = 1;
  28. if(isupper(line[j])) { buf[line[j]-'A'][0][0] = i; buf[line[j]-'A'][0][1] = j; sign[line[j]-'A'] = 1; }
  29. else { buf[line[j]-'a'][1][0] = i; buf[line[j]-'a'][1][1] = j; sign[line[j]-'a'] = 1; }
  30. }
  31. }
  32. }
  33. memset(vis, 0, sizeof(vis));
  34. for(int i = 0; i < 26; i++)
  35. if(sign[i]) {
  36. st[cnt][0] = buf[i][1][0]; st[cnt][1] = buf[i][1][1];
  37. ed[cnt][0] = buf[i][0][0]; ed[cnt++][1] = buf[i][0][1];
  38. }
  39. return true;
  40. }
  41. int toInt(int (&arr)[4][2]) {
  42. int temp = 0;
  43. for(int i = 0; i < n; i++) {
  44. temp = (((temp<<4)|arr[i][0]) << 4) | arr[i][1];
  45. }
  46. return temp;
  47. }
  48. #ifdef LOCAL
  49. #include<algorithm>
  50. void output(int num) {
  51. string line;
  52. do {
  53. line += num%2+'0';
  54. num /= 2;
  55. } while(num);
  56. reverse(line.begin(), line.end());
  57. cout << line << endl;
  58. }
  59. #endif
  60. void output(int (&arr)[4][2]) {
  61. for(int i = 0; i < n; i++) cout << arr[i][0] << " " << arr[i][1] << " ";
  62. cout << endl;
  63. }
  64. void toPos(int num, int (&arr)[4][2]) {
  65. for(int i = n-1; i >= 0; i--) {
  66. arr[i][1] = num & debase;
  67. num = num >> base;
  68. arr[i][0] = num & debase;
  69. num = num >> base;
  70. }
  71. }
  72. void findPath(vector<int> &v, int cur, int (&npos)[4][2], int (&pos)[4][2]) {
  73. if(cur == n) {
  74. for(int i = 0; i < n; i++)
  75. for(int j = i+1; j < n; j++)
  76. if((npos[i][0] == npos[j][0] && npos[i][1] == npos[j][1]) || (npos[i][0]==pos[j][0] && npos[i][1]==pos[j][1] && npos[j][0]==pos[i][0] && npos[j][1]==pos[i][1])) return;
  77. int temp = toInt(npos);
  78. if(!vis[temp]) {
  79. vis[temp] = true;
  80. v.push_back(temp);
  81. }
  82. return;
  83. }
  84. for(int i = 0; i < 5; i++) {
  85. int nx = pos[cur][0] + dx[i], ny = pos[cur][1] + dy[i];
  86. if(nx >= 0 && nx < h && ny >= 0 && ny < w && G[nx][ny]) {
  87. npos[cur][0] = nx; npos[cur][1] = ny;
  88. findPath(v, cur+1, npos, pos);
  89. }
  90. }
  91. }
  92. int main() {
  93. while(getD()) {
  94. sta = toInt(st);
  95. des = toInt(ed);
  96. queue<Node> q;
  97. q.push(Node(sta, 0));
  98. int ans = 0;
  99. vis[sta] = true;
  100. while(!q.empty()) {
  101. Node temp = q.front(); q.pop();
  102. if(temp.value == des) { ans = temp.costed; break; }
  103. int pos[4][2], npos[4][2];
  104. toPos(temp.value, pos);
  105. vector<int> v;
  106. findPath(v, 0, npos, pos);
  107. for(int i = 0; i < v.size(); i++) q.push(Node(v[i], temp.costed+1));
  108. }
  109. cout << ans << endl;
  110. }
  111. return 0;
  112. }

注意,对于这种转移代价高的,我们要想办法减少转移代价,因为其实题目中有很多障碍格,因此并不是所有四个方向都能移动,因此可以把所有空格提出来建立一张图,而不是每次临时判断5中方法是否合法

其次,是换一个算法,例如双向广度优先搜索,双向BFS首先需要直到起点和终点,然后就可以正着搜索一层,反着搜索一层,这样交替下去,直到两层中出现相同的状态

A算法也是挺好的,不过此时就是使用优先队列,A算法最重要的就是估值函数的选取,

f(x) = h(x) + g(x)

h(x):是当前到x所需要花费的代价

g(x):启发式信息,根据x推断到达终点所需要花费的代价,一个好的启发式算法可以大大减少需要搜索遍历到的点

7.5 The Morning after Halloween的更多相关文章

  1. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  2. Lightoj 题目1422 - Halloween Costumes(区间DP)

    1422 - Halloween Costumes   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...

  3. CSUFT 1004 This is Halloween: Saving Money

    1004: This is Halloween: Saving Money Time Limit: 1 Sec      Memory Limit: 128 MB Submit: 11      So ...

  4. [POJ 3370] Halloween treats

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7143   Accepted: 2641 ...

  5. poj 3370 Halloween treats(鸽巢原理)

    Description Every year there is the same problem at Halloween: Each neighbour is only willing to giv ...

  6. LightOJ - 1422 Halloween Costumes (区间dp)

    Description Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he i ...

  7. UVA 11237 - Halloween treats(鸽笼原理)

    11237 - Halloween treats option=com_onlinejudge&Itemid=8&page=show_problem&category=516& ...

  8. 鸽巢原理应用-分糖果 POJ 3370 Halloween treats

    基本原理:n+1只鸽子飞回n个鸽笼至少有一个鸽笼含有不少于2只的鸽子. 很简单,应用却也很多,很巧妙,看例题: Description Every year there is the same pro ...

  9. UVA1601-The Morning after Halloween(双向BFS)

    Problem UVA1601-The Morning after Halloween Accept: 289 Submit: 3136 Time Limit: 12000 mSec  Problem ...

  10. [uva P1601] The Morning after Halloween

    [uva P1601] The Morning after Halloween 题目链接 非常经典的一道题目,lrj的书上也有(貌似是紫书?). 其实这题看起来就比较麻烦.. 首先要保证小鬼不能相遇, ...

随机推荐

  1. Django学习——图书相关表关系建立、基于双下划线的跨表查询、聚合查询、分组查询、F查询、Q查询、admin的使用、使用脚本调用Django、Django查看源生sql

    0 图书相关表关系建立 1.5个表 2.书籍表,作者表,作者详情表(垂直分表),出版社表,书籍和作者表(多对多关系) 一对一 多对多 本质都是一对多 外键关系 3.一对一的关系,关联字段可以写在任意一 ...

  2. 1.ArrayList和LinkedList区别

    说⼀下ArrayList和LinkedList区别 具体区别 1.1. ⾸先,他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的 1.2. 由于底 ...

  3. java高级用法之:JNA中的Function

    目录 简介 function的定义 Function的实际应用 总结 简介 在JNA中,为了和native的function进行映射,我们可以有两种mapping方式,第一种是interface ma ...

  4. linux下nginx软件的学习

    参考博客 1.nginx是什么 nginx是一个开源的,支持高性能,高并发的web服务和代理服务软件.它是开源的软件. nginx比它大哥apache性能改进许多,nginx占用的系统资源更少,支持更 ...

  5. Blazor和Vue对比学习(基础1.4):事件和子传父

    Blazor和Vue的组件事件,都使用事件订阅者模式.相对于上一章的组件属性,需要多绕一个弯,无论Blazor还是Vue,都是入门的第一个难点.要突破这个难点,一是要熟悉事件订阅模式<其实不难& ...

  6. Golang 的 `[]interface{}` 类型

    Golang 的 []interface{} 类型 我其实不太喜欢使用 Go 语言的 interface{} 类型,一般情况下我宁愿多写几个函数:XxxInt, XxxFloat, XxxString ...

  7. 关于扑克牌的一些讨论——《Fluent Python 2》读书笔记

    一.说明 参考资料为维基百科的 Playing Card 词条,非严肃性论证,只是对代码为什么这么写做讨论. 二.扑克牌的起源 import collections Card = collection ...

  8. Angular中懒加载一个模块并动态创建显示该模块下声明的组件

    angular中支持可以通过路由来懒加载某些页面模块已达到减少首屏尺寸, 提高首屏加载速度的目的. 但是这种通过路由的方式有时候是无法满足需求的. 比如, 点击一个按钮后显示一行工具栏, 这个工具栏组 ...

  9. 渗透:wesside-ng

    WEP自动破解工具wesside-ng wesside-ng是aircrack-ng套件提供的一个概念验证工具.该工具可以自动扫描无线网络,发现WEP加密的AP.然后,尝试关联该AP.关联成功后,它会 ...

  10. nginx 主运行配置详解(nginx.conf)

    #==基础配置==# user nginx; #设置运行用户,当运行NGINX时,进程所使用的用户,则进程拥有该用户对文件或目录的操作权限. worker_processes 4; #设置工作进程数量 ...