博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)...
阅读量:5340 次
发布时间:2019-06-15

本文共 3366 字,大约阅读时间需要 11 分钟。

这题数据大容易TLE

优化:预处理, 可以先枚举出5^3的状态然后判断合不合法,但是由于题目说了有很多墙壁,实际上没有那么多要转移的状态那么可以把底图抽出来,然后3个ghost在上面跑到时候就不必判断了,减少了两次无用的枚举。

 

减少代码的方法:1.结点没有3个时增加冗余点,2.把位置坐标二元组编号成一个数,这点在预处理时可以顺便完成(坐标范围0~15),3.把三个ghost的位置状态压缩成一个数字,方便push,但是注意重时不能直接用Hash掉的值来判断vis,因为Hash以后数字范围很大。

这题为什么不适合Astar。因为Astar的估计用Manhattan距离需要知道坐标,因此不适合把二元组hash成数字,而且不能用一个数来压缩状态了,因为要加上估价值,代码很长,容易写错。

学习点:

1.减少代码量的方法,减少分类,提取不同的问题的相同部分

2.建图的方法。

poj不支持#include<bits/stdc++.h>

//Rey#include
using namespace std;const int maxw = 16;const int maxn = 150;//14*14*3/4+2 149int s[3];int t[3];int w,h,n;char maze[maxw][maxw+1];int deg[maxn],G[maxn][5];inline bool conflict(int a1,int b1,int a2,int b2){ return a1 == a2 || (a1 == b2 && a2 == b1);}int vis1[maxn][maxn][maxn];int vis2[maxn][maxn][maxn];typedef vector
VINT;VINT v1;VINT v2;VINT v3;typedef VINT * PV;inline int Hash(int a,int b,int c) {
return a<<16|b<<8|c;}int dBfs(){ v1.clear();v2.clear();v3.clear(); memset(vis1,-1,sizeof(vis1)); memset(vis2,-1,sizeof(vis2)); PV q1 = &v1,q2 = &v2,nxt = &v3; int (*d1)[maxn][maxn] = vis1, (*d2)[maxn][maxn] = vis2; d1[s[0]][s[1]][s[2]] = 0; d2[t[0]][t[1]][t[2]] = 0; q1->push_back(Hash(s[0],s[1],s[2])); q2->push_back(Hash(t[0],t[1],t[2])); while(q1->size()&&q2->size()){ if(q1->size()>q2->size()) swap(q1,q2),swap(d1,d2); for(int ii = 0,sz = q1->size(); ii < sz; ii++){ int u = (*q1)[ii]; int a = u>>16, b = (u>>8)&0xff, c = u&0xff; for(int i = 0; i < deg[a]; i++){ int a1 = G[a][i]; for(int j = 0; j < deg[b]; j++){ int b1 = G[b][j]; if(conflict(a1,a,b1,b)) continue; for(int k = 0; k < deg[c]; k++){ int c1 = G[c][k]; if(conflict(c1,c,a1,a)||conflict(c1,c,b1,b)||~d1[a1][b1][c1]) continue; d1[a1][b1][c1] = d1[a][b][c]+1; if(~d2[a1][b1][c1]) { return d1[a1][b1][c1]+d2[a1][b1][c1]; } nxt->push_back(Hash(a1,b1,c1)); } } } } q1->clear(); swap(nxt,q1); } return -1;}void init(){ int cnt = 0; int id[maxw][maxw]; const int dx[] = {-1, 1, 0, 0, 0}; const int dy[] = { 0, 0,-1, 1, 0}; int x[maxn]; int y[maxn]; for(int i = 0; i < h; i++) for(int j = 0; j < w; j++) { char ch = maze[i][j]; if(ch != '#'){ x[cnt] = i; y[cnt] = j; id[i][j] = cnt; if('A'<= ch && ch <= 'C') {t[ch-'A'] = cnt;} else if('a' <= ch && ch <= 'c') {s[ch-'a'] = cnt; } cnt++; } } for(int i = 0; i < cnt; i++){ deg[i] = 0; for(int k = 0; k < 5; k++) { int nx = x[i]+dx[k], ny = y[i]+dy[k]; if(maze[nx][ny] != '#') G[i][deg[i]++] = id[nx][ny]; } } if(n<=2) {deg[cnt] = 1; G[cnt][0] = cnt; s[2] = t[2] = cnt++; } if(n<=1) {deg[cnt] = 1; G[cnt][0] = cnt; s[1] = t[1] = cnt++; }}int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d",&w)&&w) { scanf("%d%d\n",&h,&n); for(int i = 0; i < h; i++) gets(maze[i]);//G[i-1] init(); int ans = dBfs(); printf("%d\n",ans); } return 0;}

 

转载于:https://www.cnblogs.com/jerryRey/p/4625821.html

你可能感兴趣的文章
webstorm修改文件,webpack-dev-server不会自动编译刷新
查看>>
Scikit-learn 库的使用
查看>>
CSS: caption-side 属性
查看>>
python 用数组实现队列
查看>>
认证和授权(Authentication和Authorization)
查看>>
Mac上安装Tomcat
查看>>
CSS3中box-sizing的理解
查看>>
传统企业-全渠道营销解决方案-1
查看>>
Lucene全文检索
查看>>
awk工具-解析1
查看>>
推荐一款可以直接下载浏览器sources资源的Chrome插件
查看>>
CRM product UI里assignment block的显示隐藏逻辑
查看>>
展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告...
查看>>
AMH V4.5 – 基于AMH4.2的第三方开发版
查看>>
Mac下安装npm全局包提示权限不够
查看>>
Web.Config文件配置之配置Session变量的生命周期
查看>>
mysql导入source注意点
查看>>
Python: 对于DataFrame.loc传入列表和传入元组输出区别的理解
查看>>
USACO / Sorting a Three-Valued Sequence (简单题,方法正确性待证)
查看>>
Android开发中 .9.png格式图形设计:
查看>>