UVa1601万圣节后的早晨
本题并不是我自己想出来的,仅仅只是看懂了刘汝佳的源代码,然后自己想着敲了一遍,也许我写得不好,不过只要对大家有点帮助就还行。
本题运用到几个小技巧和大家分享一下:
1)添加虚拟节点,使它更方便BFS。
2)用二进制映射状态,方便入队和出队。
3)使用数组来变换方向
另外,假如你没有进行优化直接用原图BFS,那么肯定是会超时的,在这里就有一种优化方法。可以将原图存好后把字母和空格单独剔出来,因为‘#’它是不访问的。这样就可以减少你搜索的次数,以此来优化。还有就是在BFS时,如果用原数据BFS也肯定是会超时的,这时我们就可以用二进制来进行状态压缩,以此来减少很多入队和出队的时间。
下面是我的代码和注释
#include<cstdio>
#include<queue>
#include<cstring>
#include<cctype>
using namespace std;const int maxn = 150;///空格占大约75%
const int maxs = 20;
const int dx[]={1,-1,0,0,0};///用于行上的位置变化
const int dy[]={0,0,1,-1,0};///用于列上的位置变化int n,m,z,id[maxs][maxs];
int s[3],t[3],G[maxn][5],dig[maxn];int d[maxn][maxn][maxn];///表示当前状态到原点的距离int ID(int k1,int k2,int k3){return (k1<<16)|(k2<<8)|k3;///用二进制压缩
}bool pd(int a,int b,int a2,int b2){return a2 == b2 || (a2 == b && b2 == a);
}int bfs(){queue<int >q;memset(d,-1,sizeof(d));q.push(ID(s[0],s[1],s[2]));///使三个初始节点映射成一个值,方便入队和出对d[s[0]][s[1]][s[2]] = 0;///第一个状态到自己,距离为零while(!q.empty()){int u = q.front();q.pop();int a = (u>>16)&0xff,b = (u>>8)&0xff,c = u&0xff;///分离出之前的三个节点if(a == t[0] && b == t[1] && c == t[2])return d[a][b][c];///判断是否到达目标节点for(int i = 0;i < dig[a]; i++){int a2 = G[a][i];///第一个节点能到的节点for(int j = 0;j < dig[b]; j++){int b2 = G[b][j];///第二个节点能到的节点if(pd(a,b,a2,b2))continue;///判断是否合法for(int k = 0;k < dig[c]; k++){int c2 = G[c][k];///第三个节点能到的节点if(pd(a,c,a2,c2))continue;///判断是否合法if(pd(b,c,b2,c2))continue;///判断是否合法if(d[a2][b2][c2] != -1)continue;///剪枝d[a2][b2][c2] = d[a][b][c] + 1;///移动一次q.push(ID(a2,b2,c2));///移动后映射入队}}}}return -1;
}int main(){while(scanf("%d%d%d",&n,&m,&z) == 3 && n){char aa[20][20];for(int i1 = 0;i1 <= m;i1++)fgets(aa[i1],20,stdin);///可以将空格也一起读入int x[maxn],y[maxn];int cnt = 0;///可以记录节点编号for(int i = 0;i < m; i++){///行for(int j = 0;j < n; j++){///列if(aa[i][j] != '#'){x[cnt] = i; ///记录该节点在那行y[cnt] = j; ///记录该节点在那列id[i][j] = cnt; ///用一个二维数组把节点编号存下来if(islower(aa[i][j])){ ///判断该字符是否为小写字母s[aa[i][j] - 'a'] = cnt;///记录给该字母的节点编号}else if(isupper(aa[i][j])){ ///判断该字符是否为大写字母t[aa[i][j] - 'A'] = cnt;}cnt++;}}}for(int i = 0;i < cnt; i++){ ///开始遍历每个节点dig[i] = 0; ///用来存能与该节点相连的节点的数量for(int dir = 0;dir < 5; dir++){ ///方向变化int nx = x[i] + dx[dir],ny = y[i] + dy[dir];///变化后的横纵坐标if(aa[nx][ny] != '#'){G[i][dig[i]++] = id[nx][ny]; ///记录该节点与他能到的节点,以此建图。}}}if(z <= 2){dig[cnt] = 1;G[cnt][0] = cnt;s[2] = t[2] = cnt++;}///添加虚拟节点if(z <= 1){dig[cnt] = 1;G[cnt][0] = cnt;s[1] = t[1] = cnt++;}///添加虚拟节点printf ("%d\n",bfs());}
}
希望对你有帮助。
UVa1601万圣节后的早晨相关推荐
- 万圣节后的早晨九数码游戏——双向广搜
https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...
- 万圣节 数据_将万圣节特效带入WordPress网站的7种方法
万圣节 数据 Do you want to add Halloween effects to your WordPress site? Holidays are the perfect time to ...
- 节后综合症太痛苦,人工智能有“良方”
面对精神萎靡的节后综合症患者,跟自我调节的"死方法"相比,人工智能似乎更为强大! 今年的最后一个节日--国庆节已经悄然走过.在这难得的7天长假内,我们经历了堵车.景区"看 ...
- OSChina 周一乱弹 ——节后突然不想上班的节奏
2019独角兽企业重金招聘Python工程师标准>>> [今日歌曲推荐] Shots (feat. Broiler) [Broiler Remix] - Imagine Dragon ...
- 为什么很多优秀的人,都把闹钟定在早晨5:57 ?
本文作者书单君,转载自微信公众号"书单"(id:BookSelection),由来自<南方周末>.<新京报>等媒体的资深媒体人共同打造,帮你提升自己,通过读 ...
- 【连载】高效人士的116个IT秘诀(第2版)——秘诀23早晨就来一次突破
下一篇:[连载]高效人士的116个IT秘诀(第2版)--秘诀24为你的时间建一个构造图 等级--初级 平台--全部 成本--免费 你很享受在待办事项列表上划掉一个事项时的那种满足感和成就感,搞定了,完 ...
- 为什么很多优秀的人,把闹钟定在早晨5:57?
关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 你知道吗?很多知名企业家,比如苹果前 CEO 乔布斯.著名投资人杰夫·乔丹等,他们 ...
- 节后开工,请把这9句话写在你的办公桌上!
节后开工,应该写在办公桌上的9句话. 1.不为模糊不清的未来担忧,只为清清楚楚的现在努力 2.只有先改变自己的态度,才能改变人生的高度 3.在抱怨自己赚钱少之前,先努力,学着让自己值钱 4.学历代表过 ...
- 就是好骑!骑ofo小黄蜂和舒畅早晨say hi,跟闹心堵车say bye
每个工作日的早晨,在北上广深这些超级城市的通勤站点,到处是哈欠连天.裹挟着起床气的上班族,他们身上散发着熬夜的疲惫和迟到的焦虑,在早高峰的长队里小碎步挪动,恨不能有一扇任意门让自己瞬间穿越到公司. 对 ...
最新文章
- RGB Color Codes Chart
- seq2seq模型_直观理解并使用Tensorflow实现Seq2Seq模型的注意机制
- linux 僵尸进程 defunct
- 错过618?暑假阅读季不要错过啦!
- yolov5 v3.0训练出现KeyError错误
- 关于Servlet和异步Servlet
- react native+typescript创建移动端项目-(慕课网喜马拉雅项目笔记)-(二,导航器navigator)
- XenCenter创建VM过程
- matlab更改安全密钥,Linux下设置安全密钥登录
- libmodbus之嵌入式Linux使用及测试
- [C语言]——打印素数(质数)
- hulu dpp_如何将Hulu视频下载到您的PC以便离线观看
- React 混合中英文计算字符长度
- 第4章内容-启动豆果美食并抓包
- 360cdn能挡住cc攻击_又被CC攻击弄得心有余悸?莫怕!这里教你如何防御
- 维夏英语暑期调研小分队——第二天
- 用tensorflow深度学习梵高的画并模仿
- CSSJS弹出层效果,兼容所有浏览器
- 你为什么选择计算机这个专业英语,英文作文:为什么选择计算机作为你的专业...
- 大数据好学么?具体学什么?
热门文章
- 广西新业态增收 国稻种芯·中国水稻节:梧州岑溪订单种植水稻
- k-9 邮箱添加 qq、163、gmail 帐号
- 互联网晚报 | 7月17日 星期日 | iPhone 14量产在即;首款国产科学计算软件研发成功;上半年广东人均收入2.47万元...
- 生活细语:送给每一个热爱生活的人[ 收集整理,超强!!!]
- JS中终止函数执行的代码
- 打开word时提示需要安装包gaozhi.msi
- Windows下安装Nexus私服及更新索引
- 三,c程序的编辑,编译,链接和运行
- 千寻位置千寻知寸测试
- 《Spring系列》第15章 声明式事务(一) 基础使用