本题并不是我自己想出来的,仅仅只是看懂了刘汝佳的源代码,然后自己想着敲了一遍,也许我写得不好,不过只要对大家有点帮助就还行。

本题运用到几个小技巧和大家分享一下:

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万圣节后的早晨相关推荐

  1. 万圣节后的早晨九数码游戏——双向广搜

    https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...

  2. 万圣节 数据_将万圣节特效带入WordPress网站的7种方法

    万圣节 数据 Do you want to add Halloween effects to your WordPress site? Holidays are the perfect time to ...

  3. 节后综合症太痛苦,人工智能有“良方”

    面对精神萎靡的节后综合症患者,跟自我调节的"死方法"相比,人工智能似乎更为强大! 今年的最后一个节日--国庆节已经悄然走过.在这难得的7天长假内,我们经历了堵车.景区"看 ...

  4. OSChina 周一乱弹 ——节后突然不想上班的节奏

    2019独角兽企业重金招聘Python工程师标准>>> [今日歌曲推荐] Shots (feat. Broiler) [Broiler Remix] - Imagine Dragon ...

  5. 为什么很多优秀的人,都把闹钟定在早晨5:57 ?

    本文作者书单君,转载自微信公众号"书单"(id:BookSelection),由来自<南方周末>.<新京报>等媒体的资深媒体人共同打造,帮你提升自己,通过读 ...

  6. 【连载】高效人士的116个IT秘诀(第2版)——秘诀23早晨就来一次突破

    下一篇:[连载]高效人士的116个IT秘诀(第2版)--秘诀24为你的时间建一个构造图 等级--初级 平台--全部 成本--免费 你很享受在待办事项列表上划掉一个事项时的那种满足感和成就感,搞定了,完 ...

  7. 为什么很多优秀的人,把闹钟定在早晨5:57?

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 你知道吗?很多知名企业家,比如苹果前 CEO 乔布斯.著名投资人杰夫·乔丹等,他们 ...

  8. 节后开工,请把这9句话写在你的办公桌上!

    节后开工,应该写在办公桌上的9句话. 1.不为模糊不清的未来担忧,只为清清楚楚的现在努力 2.只有先改变自己的态度,才能改变人生的高度 3.在抱怨自己赚钱少之前,先努力,学着让自己值钱 4.学历代表过 ...

  9. 就是好骑!骑ofo小黄蜂和舒畅早晨say hi,跟闹心堵车say bye

    每个工作日的早晨,在北上广深这些超级城市的通勤站点,到处是哈欠连天.裹挟着起床气的上班族,他们身上散发着熬夜的疲惫和迟到的焦虑,在早高峰的长队里小碎步挪动,恨不能有一扇任意门让自己瞬间穿越到公司. 对 ...

最新文章

  1. RGB Color Codes Chart
  2. seq2seq模型_直观理解并使用Tensorflow实现Seq2Seq模型的注意机制
  3. linux 僵尸进程 defunct
  4. 错过618?暑假阅读季不要错过啦!
  5. yolov5 v3.0训练出现KeyError错误
  6. 关于Servlet和异步Servlet
  7. react native+typescript创建移动端项目-(慕课网喜马拉雅项目笔记)-(二,导航器navigator)
  8. XenCenter创建VM过程
  9. matlab更改安全密钥,Linux下设置安全密钥登录
  10. libmodbus之嵌入式Linux使用及测试
  11. [C语言]——打印素数(质数)
  12. hulu dpp_如何将Hulu视频下载到您的PC以便离线观看
  13. React 混合中英文计算字符长度
  14. 第4章内容-启动豆果美食并抓包
  15. 360cdn能挡住cc攻击_又被CC攻击弄得心有余悸?莫怕!这里教你如何防御
  16. 维夏英语暑期调研小分队——第二天
  17. 用tensorflow深度学习梵高的画并模仿
  18. CSSJS弹出层效果,兼容所有浏览器
  19. 你为什么选择计算机这个专业英语,英文作文:为什么选择计算机作为你的专业...
  20. 大数据好学么?具体学什么?

热门文章

  1. 广西新业态增收 国稻种芯·中国水稻节:梧州岑溪订单种植水稻
  2. k-9 邮箱添加 qq、163、gmail 帐号
  3. 互联网晚报 | 7月17日 星期日 | iPhone 14量产在即;首款国产科学计算软件研发成功;上半年广东人均收入2.47万元...
  4. 生活细语:送给每一个热爱生活的人[ 收集整理,超强!!!]
  5. JS中终止函数执行的代码
  6. 打开word时提示需要安装包gaozhi.msi
  7. Windows下安装Nexus私服及更新索引
  8. 三,c程序的编辑,编译,链接和运行
  9. 千寻位置千寻知寸测试
  10. 《Spring系列》第15章 声明式事务(一) 基础使用