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

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

点击查看笔者代码
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std; constexpr int maxl = 16, maxn = 16777216+5, base = 4, debase = 15;
int w, h, n, des, sta, st[maxl/4][2], ed[maxl/4][2], G[maxl][maxl];
int dx[5] = {0, 0, 0, 1, -1};
int dy[5] = {0, 1, -1, 0, 0};
bool vis[maxn]; struct Node{
int value, costed;
Node(int value = 0, int costed = 0) : value(value), costed(costed) {}
}; bool getD() {
cin >> w >> h >> n;
if(!w) return false;
int cnt = 0, buf[26][2][2], sign[26]; memset(sign, 0, sizeof(sign));
string line; getline(cin, line); memset(G, 1, sizeof(G));
for(int i = 0; i < h; i++) {
getline(cin, line);
int len = line.length();
for(int j = 0; j < len; j++) {
if(line[j] == ' ') G[i][j] = 1;
else if(line[j] == '#') G[i][j] = 0;
else {
G[i][j] = 1;
if(isupper(line[j])) { buf[line[j]-'A'][0][0] = i; buf[line[j]-'A'][0][1] = j; sign[line[j]-'A'] = 1; }
else { buf[line[j]-'a'][1][0] = i; buf[line[j]-'a'][1][1] = j; sign[line[j]-'a'] = 1; }
}
}
}
memset(vis, 0, sizeof(vis));
for(int i = 0; i < 26; i++)
if(sign[i]) {
st[cnt][0] = buf[i][1][0]; st[cnt][1] = buf[i][1][1];
ed[cnt][0] = buf[i][0][0]; ed[cnt++][1] = buf[i][0][1];
}
return true;
} int toInt(int (&arr)[4][2]) {
int temp = 0;
for(int i = 0; i < n; i++) {
temp = (((temp<<4)|arr[i][0]) << 4) | arr[i][1];
}
return temp;
} #ifdef LOCAL
#include<algorithm>
void output(int num) {
string line;
do {
line += num%2+'0';
num /= 2;
} while(num);
reverse(line.begin(), line.end());
cout << line << endl;
}
#endif void output(int (&arr)[4][2]) {
for(int i = 0; i < n; i++) cout << arr[i][0] << " " << arr[i][1] << " ";
cout << endl;
} void toPos(int num, int (&arr)[4][2]) {
for(int i = n-1; i >= 0; i--) {
arr[i][1] = num & debase;
num = num >> base;
arr[i][0] = num & debase;
num = num >> base;
}
} void findPath(vector<int> &v, int cur, int (&npos)[4][2], int (&pos)[4][2]) {
if(cur == n) {
for(int i = 0; i < n; i++)
for(int j = i+1; j < n; j++)
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;
int temp = toInt(npos);
if(!vis[temp]) {
vis[temp] = true;
v.push_back(temp);
}
return;
}
for(int i = 0; i < 5; i++) {
int nx = pos[cur][0] + dx[i], ny = pos[cur][1] + dy[i];
if(nx >= 0 && nx < h && ny >= 0 && ny < w && G[nx][ny]) {
npos[cur][0] = nx; npos[cur][1] = ny;
findPath(v, cur+1, npos, pos);
}
}
} int main() {
while(getD()) {
sta = toInt(st);
des = toInt(ed);
queue<Node> q;
q.push(Node(sta, 0));
int ans = 0;
vis[sta] = true;
while(!q.empty()) {
Node temp = q.front(); q.pop();
if(temp.value == des) { ans = temp.costed; break; }
int pos[4][2], npos[4][2];
toPos(temp.value, pos);
vector<int> v;
findPath(v, 0, npos, pos);
for(int i = 0; i < v.size(); i++) q.push(Node(v[i], temp.costed+1));
}
cout << ans << endl;
}
return 0;
}

注意,对于这种转移代价高的,我们要想办法减少转移代价,因为其实题目中有很多障碍格,因此并不是所有四个方向都能移动,因此可以把所有空格提出来建立一张图,而不是每次临时判断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. 使用本地自签名证书为 React 项目启用 https 支持

    简介 现在是大前端的时代,我们在本地开发 React 项目非常方便.这不是本文的重点,今天要分享一个话题是,如何为这些本地的项目,添加 https 的支持.为什么要考虑这个问题呢?主要有几个原因 如果 ...

  2. SQL注入之information_schema

    在学习SQL注入时, 经常拿出来的例子就是PHP+MySQL这一套经典组合. 其中又经常提到的>=5.0版本的MySQL的内置库: information_schema 简单看一下informa ...

  3. JavaScript 任务池

    JavaScript 任务池 本文写于 2022 年 5 月 13 日 线程池 在多线程语言中,我们通常不会随意的在需要启动线程的时候去启动,而是会选择创建一个线程池. 所谓线程池,本意其实就是(不止 ...

  4. 使用Husky提升你的项目规范

    使用 ESLint, Prettier, Husky, Lint-staged 提升你的项目规范 本文写于 2020 年 11 月 7 日 大家应该都知道 ESLint 与 prettier,他们的用 ...

  5. Redis设计与实现3.2:Sentinel

    Sentinel哨兵 这是<Redis设计与实现>系列的文章,系列导航:Redis设计与实现笔记 哨兵:监视.通知.自动故障恢复 启动与初始化 Sentinel 的本质只是一个运行在特殊模 ...

  6. 105_Power Pivot财务科目(层级深度&筛选深度)

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 1.背景 在财务科目中,需要按照科目层级来显示:在excel中都是用公式来实现,而且对于数据的管理及更新是一件头痛的事情, ...

  7. MyBatis 结果映射总结

    前言 结果映射指的是将数据表中的字段与实体类中的属性关联起来,这样 MyBatis 就可以根据查询到的数据来填充实体对象的属性,帮助我们完成赋值操作.其实 MyBatis 的官方文档对映射规则的讲解还 ...

  8. [NOI2011]阿狸打字机

    题意:一开始是个空串s,有三种操作:(1.末尾加一个字符 2.末尾减一个字符 3.存储该字符串) 思路: 一开始在trie树上动态加点很好处理,3操作的时候记录一下此时trie树上的pos,同时记录d ...

  9. midway的使用教程

    一.写在前面 先说下本文的背景,这是一道笔者遇到的Node后端面试题,遂记录下,通过本文的阅读,你将对楼下知识点有所了解: midway项目的创建与使用 typescript在Node项目中的应用 如 ...

  10. 点亮Arduino内置的LED灯

    更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年9月3日. 15块软妹币的板子镇楼. 上一篇配置好了开发环境,然后就开始搞第一个小灯的实验了. 原理相当的简单, ...