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

这边笔者采用暴力的思想直接硬开所有情况的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. 如何彻底禁止 macOS Monterey 自动更新,去除更新标记和通知

    请访问原文链接:如何彻底禁止 macOS Monterey 自动更新,去除更新标记和通知,查看最新版.原创作品,转载请保留出处. 作者主页:www.sysin.org 随着 macOS Montere ...

  2. psexec.py规避杀软

    前言 在内网渗透中,当获取到一个账号密码后,经常会使用impacket套件中的psexec.py进行远程连接并执行命令,但是因为用的人多了,杀软也对psexec.py特征进行了拦截,也就导致了如果使用 ...

  3. 基于 range 的 for 循环和 auto

    基于 range 的 for 循环和 auto C++11 引入一种循环的新形式,叫基于 range 的 for 循环,它允许我们用更简单易读的形式遍历容器中的所有元素 vector<int&g ...

  4. 一图详解java-class类文件原理

    摘要:徒手制作一张超大的类文件解析图,方便通过浏览这个图能马上回忆起class文件的结构以及内部的指令. 本文分享自华为云社区<[读书会第十二期]这可能是全网"最大".&qu ...

  5. 在Vmware虚拟机(win10)中安装逍遥安卓模拟器遇到的问题及解决办法

    0x00 下载正确的安装包 逍遥模拟器官网:逍遥安卓模拟器下载官网 (xyaz.cn) 为什么要强调下载正确的安装包? 因为我在第一次下载的时候就下错了,下的是 逍遥模拟器 - 电脑玩手游神器 (me ...

  6. 纯CSS如何禁止用户复制网页的内容?

    大家好,我是半夏,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注 点赞 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师-关注公众号:搞前端的半夏,了解更多前端知 ...

  7. Docker运行资源控制

    概述 ​ 一个 docker host 上会运行若干容器,每个容器都需要 CPU.内存和 IO 资源.对于 KVM,VMware 等虚拟化技术,用户可以控制分配多少 CPU.内存资源给每个虚拟机.对于 ...

  8. Ceph集群搭建记录

    环境准备 基础环境 node00 192.168.247.144 node00 node01 192.168.247.135 node01 node02 192.168.247.143 node02 ...

  9. 模块re正则

    正则表达式 内容概要 正则表达式前戏 正则表达式之字符组 正则表达式特殊符号 正则表达式量词 正则表达式贪婪与非贪婪匹配 正则表达式取消转义 python内置模块之re模块 内容详情 正则表达式前戏 ...

  10. 微信小程序使用 ECharts

    echarts-for-weixin 是 ECharts 官方维护的一个开源项目,提供了一个微信小程序组件(Component),我们可以通过这个组件在微信小程序中使用 ECharts 绘制图表. e ...