P2864 [USACO06JAN]树林The Grove(bfs)

题面

题目描述

The pasture contains a small, contiguous grove of trees that has no 'holes' in the middle of the it. Bessie wonders: how far is it to walk around that grove and get back to my starting position? She's just sure there is a way to do it by going from her start location to successive locations by walking horizontally, vertically, or diagonally and counting each move as a single step. Just looking at it, she doesn't think you could pass 'through' the grove on a tricky diagonal. Your job is to calculate the minimum number of steps she must take.

Happily, Bessie lives on a simple world where the pasture is represented by a grid with \(R\) rows and \(C\) columns ( \(1 \leq R \leq 50, 1 \leq C \leq 50\) ). Here's a typical example where . is pasture (which Bessie may traverse), X is the grove of trees, * represents Bessie's start and end position, and + marks one shortest path she can walk to circumnavigate the grove (i.e., the answer):

  1. ...+...
  2. ..+X+..
  3. .+XXX+.
  4. ..+XXX+
  5. ..+X..+
  6. ...+++*

The path shown is not the only possible shortest path; Bessie might have taken a diagonal step from her start position and achieved a similar length solution. Bessie is happy that she's starting 'outside' the grove instead of in a sort of 'harbor' that could complicate finding the best path.

牧场里有一片树林,林子里没有坑.

贝茜很想知道,最少需要多少步能围绕树林走一圈,最后回到起点.她能上下左右走,也能走对角线格子.

牧场被分成 \(R\) 行 \(C\) 列( \(1 \leq R \leq 50,1 \leq C \leq 50\) ).下面是一张样例的地图,其中表示贝茜 可以走的空地,“X”表示树林,表示起点.而贝茜走的最近的路已经特别地用“ + ”表示 出来.

题目保证,最短的路径一定可以找到.

输入输出格式

输入格式:

Line \(1\) : Two space-separated integers: \(R\) and \(C\)

Lines \(2..R+1\) : Line \(i+1\) describes row \(i\) with \(C\) characters (with no spaces between them).

输出格式:

Line \(1\) : The single line contains a single integer which is the smallest number of steps required to circumnavigate the grove.

输入输出样例

输入样例:

  1. 6 7
  2. .......
  3. ...X...
  4. ..XXX..
  5. ...XXX.
  6. ...X...
  7. ......*

输出样例:

  1. 13

思路

艹,这题的边界判断! \(LSK\) 你试试这道题。 --zbtrs

换了三种写法,终于把神犇推荐的这道题 \(AC\) 了...

我们直接拿样例做例子:

  1. .......
  2. ...X...
  3. ..XXX..
  4. ...XXX.
  5. ...X...
  6. ......*

比如说最上面的那一颗树,我们在它上面做一条射线。

  1. .......
  2. ----
  3. ...X...
  4. ..XXX..
  5. ...XXX.
  6. ...X...
  7. ......*

那么绕树林一周的路线一定要经过这条射线。

我们可以用 \(bfs\) 更新所有点到出发点的最短距离,并且特判那条射线,要求不能跨过它:

  1. typedef pair<int,int> PII;//个人代码习惯
  2. #define mp(a,b) make_pair(a,b)//同上
  3. int a[8]={-1,-1,-1,+0,+0,+1,+1,+1};//x的变化
  4. int b[8]={-1,+0,+1,-1,+1,+1,+0,-1};//y的变化
  5. step[sx][sy]=1;
  6. queue<PII>Q;//队列
  7. Q.push(mp(sx,sy));//放入出发点
  8. while(!Q.empty())
  9. {
  10. int x=Q.front().first,y=Q.front().second;Q.pop();//取出队首点
  11. for(int i=0;i<8;i++)//枚举所有情况
  12. {
  13. int dx=x+a[i],dy=y+b[i];//能到达的点
  14. if(step[dx][dy]||!G[dx][dy]) continue;//不能到达的点和已经到过的点
  15. if(y<=ly&&x==lx&&dx==lx-1) continue;//不能从上往下穿过射线
  16. if(y<=ly&&x==lx-1&&dx==lx) continue;//不能从下往上穿过射线
  17. step[dx][dy]=step[x][y]+1;
  18. Q.push(mp(dx,dy));
  19. }
  20. }

然后就顺利 \(AC\) 了。

AC代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef pair<int,int> PII;
  4. #define mp(a,b) make_pair(a,b)
  5. int n,m,sx,sy,lx,ly,ans=INT_MAX,G[55][55],step[55][55];
  6. bool is_line_made;
  7. int a[8]={-1,-1,-1,+0,+0,+1,+1,+1};
  8. int b[8]={-1,+0,+1,-1,+1,+1,+0,-1};
  9. int main()
  10. {
  11. cin>>n>>m;
  12. for(int i=1;i<=n;i++)
  13. for(int j=1;j<=m;j++)
  14. {
  15. char ch;
  16. cin>>ch;
  17. if(ch=='*') G[i][j]=1,sx=i,sy=j;
  18. else if(ch=='.') G[i][j]=1;
  19. else if(!lx) lx=i,ly=j;
  20. }
  21. step[sx][sy]=1;
  22. queue<PII>Q;
  23. Q.push(mp(sx,sy));
  24. while(!Q.empty())
  25. {
  26. int x=Q.front().first,y=Q.front().second;Q.pop();
  27. for(int i=0;i<8;i++)
  28. {
  29. int dx=x+a[i],dy=y+b[i];
  30. if(step[dx][dy]||!G[dx][dy]) continue;
  31. if(y<=ly&&x==lx&&dx==lx-1) continue;
  32. if(y<=ly&&x==lx-1&&dx==lx) continue;
  33. step[dx][dy]=step[x][y]+1;
  34. Q.push(mp(dx,dy));
  35. }
  36. }
  37. for(int i=1;i<=ly;i++)
  38. {
  39. if(step[lx][i]&&step[lx-1][i]&&ans>step[lx][i]+step[lx-1][i]) ans=step[lx][i]+step[lx-1][i];
  40. if(step[lx][i]&&step[lx-1][i+1]&&ans>step[lx][i]+step[lx-1][i+1]) ans=step[lx][i]+step[lx-1][i+1];
  41. if(step[lx][i]&&step[lx-1][i-1]&&ans>step[lx][i]+step[lx-1][i-1]) ans=step[lx][i]+step[lx-1][i-1];
  42. }
  43. printf("%d",ans-1);
  44. return 0;
  45. }

Luogu P2864 [USACO06JAN]树林The Grove(bfs)的更多相关文章

  1. P2864 [USACO06JAN]树林The Grove

    P2864 [USACO06JAN]树林The Grove 神奇的射线法+bfs 裸的bfs很难写....... 那么我们找一个最外围障碍点,向图的外边引一条虚拟射线. 蓝后bfs时经过这条射线奇数次 ...

  2. [USACO06JAN]树林The Grove

    树木(grove)Time Limit: 1Sec Memory Limit: 64 MB[Description]牧场里有一片树林,林子里没有坑.贝茜很想知道,最少需要多少步能围绕树林走一圈,最后回 ...

  3. luogu题解P1032字串变换--BFS+STL:string骚操作

    题目链接 https://www.luogu.org/problemnew/show/P1032 分析 这题本来很裸的一个BFS,发现其中的字符串操作好烦啊.然后就翻大佬题解发现用STL中的strin ...

  4. 【POJ3182】The Grove BFS 最短路径周围

    意甲冠军:给定一个N*M图.,间'X'代表树木(树木必须汇集到森林,非分离),然后,'.'它代表的空间.'*'它代表的起点.现在它需要从起点.一圈,最后回到起点,所经过最少点数. 题目中给的'+'就是 ...

  5. poj 3182 The Grove bfs

    思路:如果要围绕一圈,必须经过一条竖线上的一点,把竖线左端封住,bfs一次,枚举点,再把竖线右端封住,再bfs回起点. #include <iostream> #include <c ...

  6. 【luogu P2860 [USACO06JAN]冗余路径Redundant Paths】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2860 考虑在无向图上缩点. 运用到边双.桥的知识. 缩点后统计度为1的点. 度为1是有一条路径,度为2是有两 ...

  7. 【luogu P2863 [USACO06JAN]牛的舞会The Cow Prom】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2863 求强连通分量大小>自己单个点的 #include <stack> #include ...

  8. LuoGu P2863 [USACO06JAN]牛的舞会The Cow Prom

    题目传送门 这个题还是个缩点的板子题...... 答案就是size大于1的强连通分量的个数 加一个size来统计就好了 #include <iostream> #include <c ...

  9. luogu P2860 [USACO06JAN]冗余路径Redundant Paths

    题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1- ...

随机推荐

  1. 6_2.springboot2.x整合Druid和配置数据源监控

    简介 Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBoss Data ...

  2. selenium基础(参数化脚本)

    参数化脚本 什么是参数化 参数化就是用包含多组数据的参数列表,使之替换脚本中的响应常量值,这样,在脚本运行的时候,就会使用参数表中的数据来代替脚本中的常量值 由于参数表中包含了多组数据,所以执行用例时 ...

  3. Nand flash 芯片工作原理

    Nand flash 芯片型号为 Samsung K9F1208U0B,数据存储容量为 64MB,采用块页式存储管理.8 个 I/O 引脚充当数据.地址.命令的复用端口. 芯片内部存储布局及存储操作特 ...

  4. 进程监控驱动 PsSetCreateProcessNotifyRoutine

    函数原型: NTSTATUS PsSetCreateProcessNotifyRoutine( _In_ PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, _ ...

  5. 关于python程序在VS code中运行时提示文件无法找到的报错

    经过测试,在设置文件夹目录时,可以找到当前目录下的htm文件,采用with open()语句可以正常执行程序,如下图. 而当未设置当前目录,直接用vscode执行该程序时,就会报错文件无法找到File ...

  6. 使用subprocessm模块管理进程

    subprocess被用来替换一些老的模块和函数,如:os.system.os.spawn*.os.popen*.popen2.*.commands.*. subprocess的目的就是启动一个新的进 ...

  7. LintCode_1 单例模式

    从今天开始我的LintCode之旅,由于C/C++好久没有使用了,语法生疏不说,低级错误频繁出现,因此在做题之后,还会有部分时间复习语法项目. ---------------------------- ...

  8. Django之模板语言(一)

    1.Django的模板语言(简而言之,字符串替换) 1.目前为止已经学过的模板语言: 1.{{ name }}  ------>变量 2. for 循环: {% for i in book_li ...

  9. PostgreSQL的基础数据类型分析记录-转

    src:http://www.codeweblog.com/postgresql%E7%9A%84%E5%9F%BA%E7%A1%80%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E ...

  10. linux命令行实用快捷键

    打开一个命令行窗口:ctrl+alt+t 在已有的命令行窗口上开启一个新的tab:ctrl+shift+t