题目大意:

输入w h,接下来输入h行w列的图

':干净的点;  ' * ' :垃圾;  ' ' : 墙;  ' ' : 初始位置;

输出 清理掉所有垃圾的最短路径长度 无则输出-1

Sample Input

7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
0 0

Sample Output

8
49
-1

题解

用bfs求出任意两点间的距离然后转换成tsp问题,用dfs解

  1. /*
  2. 题意:给一个 n*m的图,有一个机器人从一点开始清理垃圾,要求把所有的垃圾清理完,求最短的路径
  3.  
  4. 思路:这个题可以先用bfs求出任意两点间的距离然后转换成tsp问题,用dfs解。
  5.  
  6. 这个题还可以用状态压缩bfs写,但写了一次没过,再试试。
  7. */
  8.  
  9. #include <cstdlib>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <queue>
  13.  
  14. #define INF 0x7fffffff
  15. #define N 22
  16.  
  17. using namespace std;
  18.  
  19. struct node
  20. {
  21. int x,y,step;
  22. }p[N*N],s,e;
  23.  
  24. char map[N][N];
  25. int n,m,d[][]={,,,,,-,-,},used[N][N];
  26. int dis[N][N],ans,use[N],cnt;
  27.  
  28. bool ok(int x,int y)
  29. {
  30. return x>=&&x<n&&y>=&&y<m&&map[x][y]!='x'&&!used[x][y];
  31. }
  32.  
  33. int bfs()
  34. {
  35. memset(used,,sizeof(used));
  36. int i;
  37. queue<node> q;
  38. q.push(s);
  39. while(!q.empty())
  40. {
  41. node cur=q.front(),next;
  42. q.pop();
  43. for(i=;i<;i++)
  44. {
  45. next.x=cur.x+d[i][];
  46. next.y=cur.y+d[i][];
  47. next.step=cur.step+;
  48. if(ok(next.x,next.y))
  49. {
  50. used[next.x][next.y]=;
  51. if(next.x==e.x&&next.y==e.y)
  52. return next.step;
  53. q.push(next);
  54. }
  55. }
  56. }
  57. return INF;
  58. }
  59.  
  60. void dfs(int s,int num,int length)
  61. {
  62. int j;
  63. if(num==&&ans>length)
  64. {
  65. ans=length;
  66. return ;
  67. }
  68. if(length>ans)
  69. return ;
  70. for(j=;j<cnt;j++)
  71. {
  72. if(dis[s][j]!=INF&&!use[j])
  73. {
  74. use[j]=;
  75. length+=dis[s][j];
  76. dfs(j,num-,length);
  77. num+;
  78. length-=dis[s][j];
  79. use[j]=;
  80. }
  81. }
  82. }
  83.  
  84. int main()
  85. {
  86. int i, j, start, flag;
  87. while(scanf("%d%d",&m,&n)&&(n||m))
  88. {
  89. cnt=flag=;
  90. for(i=;i<n;i++)
  91. {
  92. scanf("%s",map[i]);
  93. for(j=;j<m;j++)
  94. {
  95. if(map[i][j]=='o'||map[i][j]=='*')
  96. {
  97. p[cnt].x=i,p[cnt].y=j;
  98. if(map[i][j]=='o')
  99. start=cnt;
  100. cnt++;
  101.  
  102. }
  103. dis[i][j]=INF;
  104. }
  105. }
  106.  
  107. //memset(dis,INF,sizeof(dis));
  108. for(i=;i<cnt;i++)
  109. for(j=i+;j<cnt;j++)
  110. {
  111. s=p[i],e=p[j],s.step=;
  112. dis[i][j]=dis[j][i]=bfs();
  113. if(dis[i][j]==INF)
  114. {
  115. flag=;
  116. break;
  117. }
  118. }
  119. /* for(i=0;i<cnt;i++)
  120. {
  121. for(j=0;j<cnt;j++)
  122. printf("%d\t",dis[i][j]);
  123. puts("");
  124. }*/
  125. if(flag)
  126. puts("-1");
  127. else
  128. {
  129. ans=INF;
  130. memset(use,,sizeof(use));
  131. use[start]=;
  132. dfs(start,cnt-,);
  133. printf("%d\n",ans);
  134. }
  135. }
  136. return ;
  137. }

状压 BFS

  1. #include <bits/stdc++.h>
  2. #define INF 0x3f3f3f3f
  3. using namespace std;
  4. struct NODE
  5. {
  6. int ni,nj,mask,len;
  7. NODE(){};
  8. NODE(int n_i,int n_j,int nmask,int nlen):
  9. ni(n_i),nj(n_j),mask(nmask),len(nlen){};
  10. };
  11. char G[][];
  12. int w,h,cnt,st_i,st_j;
  13. int vis[][][<<],flag[][];
  14. int mi[]={,,,-},mj[]={,-,,};
  15.  
  16. bool bound(int i,int j) /// 判断是否越界
  17. {
  18. return (i>h||i<||j>w||j<);
  19. }
  20. bool OK(int mask) /// 判断垃圾是否被清理
  21. {
  22. for(int i=;i<cnt;i++)
  23. if(mask & (<<i)); /// 用mask二进制的各个位表示各个垃圾
  24. else return ;
  25. return ;
  26. }
  27. int BFS()
  28. {
  29. memset(vis,,sizeof(vis));
  30. int ans=INF;
  31. queue<NODE> q;
  32. q.push(NODE(st_i,st_j,,)); /// 构造函数的便利之处
  33.  
  34. while(!q.empty())
  35. {
  36. NODE tmp=q.front(); q.pop();
  37.  
  38. if(OK(tmp.mask)) /// 返回1表明垃圾清理光了 就更新ans值
  39. {
  40. ans=min(ans,tmp.len);
  41. continue;
  42. }
  43.  
  44. if(vis[tmp.ni][tmp.nj][tmp.mask]) continue;
  45. /// 该点的mask状态已出现过 则忽略该点
  46. else vis[tmp.ni][tmp.nj][tmp.mask]=;
  47. /// 未出现过 则标记为已出现过
  48.  
  49. for(int i=;i<;i++)
  50. {
  51. int newi=tmp.ni+mi[i],newj=tmp.nj+mj[i],newmask=tmp.mask;
  52.  
  53. if(bound(newi,newj)||G[newi][newj]=='x') continue;
  54. /// 若越界或该点为墙 则忽略该点
  55.  
  56. if(G[newi][newj]=='*')
  57. newmask=tmp.mask | (<<flag[newi][newj]);
  58. /* 假如目前是三号垃圾 更新状态
  59. 即若此时tmp.mask的二进制为011(第一二号垃圾已清除)
  60. newmask=011 | 1<<3=111(第一二三号垃圾已清除)
  61. 很明显 将垃圾状态压缩 用mask的二进制表示 */
  62.  
  63. if(vis[newi][newj][newmask]) continue;
  64. /// 若该新点的该状态已出现过 则忽略该点 若无则放入队列
  65. q.push(NODE(newi,newj,newmask,tmp.len+));
  66. }
  67. }
  68. return ans==INF ? -:ans;
  69. }
  70.  
  71. int main()
  72. {
  73. while(~scanf("%d%d",&w,&h)&&(w||h))
  74. {
  75. cnt=;
  76. for(int i=;i<=h;i++)
  77. for(int j=;j<=w;j++)
  78. {
  79. scanf(" %c",&G[i][j]);
  80. if(G[i][j]=='o') st_i=i,st_j=j; /// 记下所在位置
  81. else if(G[i][j]=='*') flag[i][j]=cnt++;
  82. /// 记下垃圾的位置 并为其编号 防止重复清扫
  83. }
  84. if(!cnt) printf("0\n");
  85. else printf("%d\n",BFS());
  86. }
  87.  
  88. return ;
  89. }

Japan 2005 Domestic Cleaning Robot /// BFS 状压 二进制位运算 结构体内构造函数 oj22912的更多相关文章

  1. 孤岛营救问题 (BFS+状压)

    https://loj.ac/problem/6121 BFS + 状压 写过就好想,注意细节debug #include <bits/stdc++.h> #define read rea ...

  2. hdu 5094 Maze (BFS+状压)

    题意: n*m的迷宫.多多要从(1,1)到达(n,m).每移动一步消耗1秒.有P种钥匙. 有K个门或墙.给出K个信息:x1,y1,x2,y2,gi    含义是(x1,y1)与(x2,y2)之间有gi ...

  3. hdu 4771 Stealing Harry Potter's Precious (BFS+状压)

    题意: n*m的迷宫,有一些格能走("."),有一些格不能走("#").起始点为"@". 有K个物体.(K<=4),每个物体都是放在& ...

  4. HDU-3681-Prison Break(BFS+状压DP+二分)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  5. 【BZOJ 3049】【USACO2013 Jan】Island Travels BFS+状压DP

    这是今天下午的互测题,只得了60多分 分析一下错因: $dis[i][j]$只记录了相邻的两个岛屿之间的距离,我一开始以为可以,后来$charge$提醒我有可能会出现来回走的情况,而状压转移就一次,无 ...

  6. HDU 5025:Saving Tang Monk(BFS + 状压)

    http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Problem Description   <Journey to ...

  7. hdu 4856 Tunnels (bfs + 状压dp)

    题目链接 The input contains mutiple testcases. Please process till EOF.For each testcase, the first line ...

  8. 【HDU 4771 Stealing Harry Potter's Precious】BFS+状压

    2013杭州区域赛现场赛二水... 类似“胜利大逃亡”的搜索问题,有若干个宝藏分布在不同位置,问从起点遍历过所有k个宝藏的最短时间. 思路就是,从起点出发,搜索到最近的一个宝藏,然后以这个位置为起点, ...

  9. hdu 2209 bfs+状压

    http://acm.hdu.edu.cn/showproblem.php?pid=2209 不知为啥有种直觉.会出状压+搜索的题,刷几道先 简单的BFS.状压表示牌的状态, //#pragma co ...

随机推荐

  1. opencv打开摄像头并新建窗口显示

    几个程序使用的基本函数如下: ******************************************************************* cvCreateCameraCap ...

  2. C语言中的数据类型转换函数

    头文件#include<stdlib.h> 1. 函数名: atof 功 能: 把字符串转换成浮点数 用 法: double atof(const char *nptr); 2.函数名: ...

  3. This inspection detects shadowing names defined in outer scopes.

    错误信息:This inspection detects shadowing names defined in outer scopes. 检查到波浪处的单词已在函数外部定义. 解决:使用global ...

  4. python正则re

    import reline = "Catsaresmarterthandogs"matchObj = re.match( r'(.*)are(\w{2})(.*)', line, ...

  5. vim与ctags/cscope的完美结合

    1. 安装vim/ctags/cscope ctag 2. 在源码根目录下执行 sudo ctags -R .   会生成tags文件,里面包含着整个源码目录下的符号信息. 3. 直接到达某个符号(比 ...

  6. awesome mac

    https://proxyman.app/ https://proxie.app/docs/#how-does-it-work https://github.com/kyleduo/TinyPNG4M ...

  7. Ubuntu 14.04 64位上安装wps office软件

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/tao_627/article/details/24179933 废话少说,仅仅给出方法供各位參考! ...

  8. pytest-mark跳过

    import pytestimport sysenvironment='android' @pytest.mark.skipif(environment=="android",re ...

  9. (Struts2学习系列五)Struts2默认action

    当我们访问项目下一个不存在的Action的时候,页面就会报错,404找不到资源,这样对用户来说是非常不友好的,所以我们设置一个默认的Action,当找不到对应Action的时候,就会跳转到默认Acti ...

  10. 如何恢复误删的OneNote页面

    今天不小心把半个月的日记删掉了!(为了减少页面数量,每个月的日记会放在同一个页面上). 幸运的是OneNote有自动备份功能,喜极而泣. 操作方法来自微软支持 打开丢失了最近笔记的笔记本. 单击“文件 ...