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

这边笔者采用暴力的思想直接硬开所有情况的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. kernel heap bypass smep,smap && 劫持modprobe_path

    kernel heap bypass smep,smap && 劫持modprobe_path exp1 smep:smep即用户数据不可执行,当 CPU 处于 ring0 模式时,执 ...

  2. 不可不知的 MySQL 升级利器及 5.7 升级到 8.0 的注意事项

    数据库升级,是一项让人喜忧参半的工程.喜的是,通过升级,可以享受新版本带来的新特性及性能提升.忧的是,新版本可能与老的版本不兼容,不兼容主要体现在以下三方面: 语法不兼容. 语义不兼容.同一个SQL, ...

  3. 使用Spring MVC开发RESTful API

    第3章 使用Spring MVC开发RESTful API Restful简介 第一印象 左侧是传统写法,右侧是RESTful写法 用url描述资源,而不是行为 用http方法描述行为,使用http状 ...

  4. linux篇-修改mysql数据库密码

    总是忘记,每次都要查文档,背背背 方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = passw ...

  5. linux篇-Linux MBR分区、挂载操作步骤,逻辑卷扩容操作

    Linux  MBR分区.挂载操作步骤,逻辑卷扩容操作 服务器开机之后,能自动识别出硬盘,但是硬盘不能够存储数据,必须对硬盘进行分区.格式化.挂载后才能使用:linux主分区和拓展分区总数不能超过4个 ...

  6. Hibernate基础入门2

    HQL与Criteria HQL(Hibernate Query Language)-官方推荐面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写 ...

  7. 目标检测复习之Faster RCNN系列

    目标检测之faster rcnn系列 paper blogs1: 一文读懂Faster RCNN Faster RCNN理论合集 code: mmdetection Faster rcnn总结: 网络 ...

  8. IIS7 网站发布常见报错问题解决方案汇总

    本文实例为大家分享了IIS7 网站发布常见问题,以及五种问题的解决方法,供大家参考,具体内容如下: 1.不是有效的Win32位应用程序 : 解决方案: 1).进入应用程序池=>选中网站=> ...

  9. 使用VMware安装Ubuntu虚拟机

    一.下载安装VM软件 这一步跳过,因为网上都能找到下载地址,下载后一步一步的安装即可,网上也有很多下载地址,这里提供一个Windows的下载链接. 链接: https://pan.baidu.com/ ...

  10. STL栈与队列

    #include<queue>// 队列 #include<stack>//栈 stack<int> s;//参数也是数据类型,这是栈的定义方式 queue< ...