7.5 The Morning after Halloween
本题主要是存储的问题,在存储上笔者原先的代码占用了大量的内存空间
这边笔者采用暴力的思想直接硬开所有情况的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的更多相关文章
- POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理
Halloween treats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7644 Accepted: 2798 ...
- Lightoj 题目1422 - Halloween Costumes(区间DP)
1422 - Halloween Costumes PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...
- CSUFT 1004 This is Halloween: Saving Money
1004: This is Halloween: Saving Money Time Limit: 1 Sec Memory Limit: 128 MB Submit: 11 So ...
- [POJ 3370] Halloween treats
Halloween treats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7143 Accepted: 2641 ...
- poj 3370 Halloween treats(鸽巢原理)
Description Every year there is the same problem at Halloween: Each neighbour is only willing to giv ...
- LightOJ - 1422 Halloween Costumes (区间dp)
Description Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he i ...
- UVA 11237 - Halloween treats(鸽笼原理)
11237 - Halloween treats option=com_onlinejudge&Itemid=8&page=show_problem&category=516& ...
- 鸽巢原理应用-分糖果 POJ 3370 Halloween treats
基本原理:n+1只鸽子飞回n个鸽笼至少有一个鸽笼含有不少于2只的鸽子. 很简单,应用却也很多,很巧妙,看例题: Description Every year there is the same pro ...
- UVA1601-The Morning after Halloween(双向BFS)
Problem UVA1601-The Morning after Halloween Accept: 289 Submit: 3136 Time Limit: 12000 mSec Problem ...
- [uva P1601] The Morning after Halloween
[uva P1601] The Morning after Halloween 题目链接 非常经典的一道题目,lrj的书上也有(貌似是紫书?). 其实这题看起来就比较麻烦.. 首先要保证小鬼不能相遇, ...
随机推荐
- 命令行参数 getopt模块
getopt中的函数: getopt.getopt(sys.argv[1:], shortopts, longopts=[]) args指的是当前脚本接收的参数,它是一个列表,可以通过sys.argv ...
- 129_Power Pivot&Power BI DAX不同维度动态展示&动态坐标轴
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 某天在和那还是叫我大铁吧 交流关于季度&月度同时展示的问题,感概中国式报表真的需求很微妙. 下面来看看到 ...
- 使用 gitbook 制作自己的 html 文档
使用 gitbook 制作自己的 html 文档 步骤如下 npm install gitbook-cli -g // 全局安装 gitbook-cli <span style="te ...
- Spark在Local环境下的使用
① 将 spark-3.0.0-bin-hadoop3.2.tgz 文件上传到 Linux (cd /opt/module路径下)并解压缩 ② 修改spark-3.0.0-bin-hado ...
- SpringBoot 整合 RabbitMQ 实现消息可靠传输
消息的可靠传输是面试必问的问题之一,保证消息的可靠传输主要在生产端开启 comfirm 模式,RabbitMQ 开启持久化,消费端关闭自动 ack 模式. 环境配置 SpringBoot 整合 Rab ...
- Activate-or-Not:learning-customized-activation
关于activate-or-Not的PPT paper code step1 step2 step3 step4 step5 step6 step7 step8 step9 step10
- 第06组Alpha冲刺(6/6)
目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2.曹兰英 3. 方梓涵 4.曾丽莉 5.鲍凌函 6.杜筱 7.黄少丹 8.詹鑫冰 9.董翔云 10.吴沅静 1.3 冲刺成果展示 1.1 基 ...
- 专家PID控制仿真学习
目录 专家控制 专家系统 专家控制 学习笔记,用于记录学习 资料:<智能控制>(第四版)--刘金琨 专家系统 一.专家系统的定义 专家系统是一类包含知识和推理的智能计算机程序,其内部包含某 ...
- 架构师必备:系统容量现状checklist
正如飞机在起飞前,机长.副机长要过一遍checklist检查,确认没问题了才能起飞.楼主也整理了一个系统容量现状checklist,方便对照检查.本文搭配架构师必备:如何做容量预估和调优,食用更佳. ...
- 关于升级最新版本node.js你知道多少?
1.先检查版本 node -v 2.清除缓存 npm cache clean -f 3.全局安装管理node.js版本工具 npm install -g n 4.确认安装最新版本 n stable 5 ...