bzoj1656: [Usaco2006 Jan] The Grove 树木 (bfs+新姿势)

题目大意:一个n*m的图中,“.”可走,“X”不可走,“*”为起点,问从起点开始绕所有X一圈回到起点最少需要走多少步。

一开始看到这题,自己脑洞了下怎么写,应该是可过,然后跑去看了题解,又学会了一个新姿势。。。

上图是样例,红色笔迹是走法,需要走13步。

这显然是bfs题,问题是怎么让bfs绕这坨东西一圈,非常巧妙的思路,从任意一个X节点画一条射线与边界垂直,如下图所示。

当我们从右向左bfs的时候碰到这条线,就停止bfs;当我们绕了一圈从左向右bfs的时候碰到这条线,我们就继续走。

dist[1][x][y]表示从左向右经过这条线之后起点到(x,y)的最短距离,dist[0][x][y]表示没有经过这条线,起点到(x,y)的最短距离。当我们从左向右经过这条线后的bfs我们就只更新dist[1][x][y],最后输出的就是dist[1][起点x][起点y]。

代码如下:

const
  dx:array[1..8]of integer=(1,0,-1,0,1,1,-1,-1);
  dy:array[1..8]of integer=(0,1,0,-1,1,-1,1,-1);
var
  n,m,i,j,fx,fy,tx,ty:longint;
  s:string;
  line,map:array[0..50,0..50]of boolean;
  dist:array[0..1,0..50,0..50]of longint;
  v:array[0..1,0..50,0..50]of boolean;
  h:array[0..1000000,1..3]of longint;

procedure bfs;
var
  i,j,k,front,rear,nx,ny,xx,yy,flag,flag2:longint;
begin
  for i:=1 to n do for j:=1 to m do for k:=0 to 1 do dist[k,i,j]:=23333333;
  dist[0,fx,fy]:=0;v[0,fx,fy]:=true;front:=0;rear:=1;h[1,1]:=fx;h[1,2]:=fy;h[1,3]:=0;
  while front<>rear do
  begin
    inc(front);
    nx:=h[front,1];ny:=h[front,2];flag:=h[front,3];
    if front=1000 then front:=0;
    for i:=1 to 8 do
    begin
      xx:=nx+dx[i];yy:=ny+dy[i];
      if (xx<0)or(xx>n)or(yy<0)or(yy>m)or(map[xx,yy])or((line[xx,yy] or line[nx,ny])and(yy<=ny))then continue;
      if (line[xx,yy])or(flag=1) then flag2:=1 else flag2:=0;
      if dist[flag,nx,ny]+1<dist[flag2,xx,yy] then
      begin
        dist[flag2,xx,yy]:=dist[flag,nx,ny]+1;
        if not v[flag2,xx,yy] then
        begin
          v[flag2,xx,yy]:=true;
          if rear=1000 then rear:=0;
          inc(rear);
          h[rear,1]:=xx;
          h[rear,2]:=yy;
          h[rear,3]:=flag2;
        end;
      end;
    end;
    v[flag,nx,ny]:=false;
  end;
  writeln(dist[1,fx,fy]);
end;

begin
  readln(n,m);
  for i:=1 to n do
  begin
    readln(s);
    for j:=1 to m do
    begin
      if s[j]=‘*‘ then
      begin
        fx:=i;fy:=j;
      end;
      if s[j]=‘X‘ then
      begin
        tx:=i;ty:=j;
        map[i,j]:=true;
      end;
    end;
  end;
  for i:=tx to n do
  line[i,ty]:=true;
  bfs;
end.

时间: 2024-10-02 21:30:39

bzoj1656: [Usaco2006 Jan] The Grove 树木 (bfs+新姿势)的相关文章

bzoj:1656: [Usaco2006 Jan] The Grove 树木

Description 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

1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会

1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 471  Solved: 339[Submit][Status][Discuss] Description The N (2 <= N <= 10,000) cows are so excited: it's prom night! They are dressed in their finest gowns, complet

BZOJ 1718: [Usaco2006 Jan] Redundant Paths 分离的路径( tarjan )

tarjan求边双连通分量, 然后就是一棵树了, 可以各种乱搞... ------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 5009; struct edge { int to; b

1718: [Usaco2006 Jan] Redundant Paths 分离的路径

1718: [Usaco2006 Jan] Redundant Paths 分离的路径 Time Limit: 5 Sec  Memory Limit: 64 MB链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1718 Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) to an

UVA 11765 Component Placement 网络流 新姿势建图

题目链接:点击打开链接 题意: 给定n个物品, m个约束条件 把n个物品分到2个集合里 下面第一行表示i物品分到第一个集合里的花费 第二行表示分到第二个集合里的花费 第三行表示分物品的限制(1表示只能分到第一个集合,-1表示只能分到第二个集合,0无限制) 下面m行给出约束条件 u v cost 表示u v 两点必须能互相沟通,若两点已经在同一集合则花费为0 ,若不在同一集合则花费增加cost 问满足m个约束条件下的最小花费 思路: 首先感觉是网络流,==建图比较难想 用流量表示费用 1.若i点放

网秦Q3财报现新姿势 老司机发力移动娱乐竟成网红

文/张书乐 日前,网秦公布了截至2016年9月30日的第三季度未经审计财务业绩.移动增值服务以同比增长74.6%至5,490万美元的成绩成为网秦营收贡献的最大板块. 老司机网秦作为国内最老牌的移动互联网"巨鳄"之一,竟然依靠移动娱乐实现了全面转型,而且网秦首席执行官许泽民更表示:"我们对移动娱乐业务领域取得的持续进展感到满意,随着2016年进入最后一个季度,我们会继续专注于执行我们的战略." 真的简单就是一个战略而已?网秦怎么就突然成了"网红"呢

【原创】多dpi适配的新姿势

多dpi适配的新姿势 简介 Android中经常要通过ImageView进行图片资源显示.在加载图片时,首先要考虑的两个因素就是体验问题和性能问题. 其中,体验问题是指图片显示的是否正确(例如Universal-Image-Loader在适配Adapter图片资源时会导致图片显示错位),图片显示尺寸是否合适,分辨率是否合适等.本文重点介绍ImageView加载图片中的显示问题. 问题 在开发的过程中,一般会将不同分辨率的图片放置在不同的文件夹中,例如将三种同样内容不同分辨率的图片分别放置在dra

Android实战——RxJava2+Retrofit+RxBinding解锁各种新姿势

RxJava2+Retrofit+RxBinding解锁各种新姿势 本篇文章内容包含以下内容 前言 RxJava2的基本介绍 RxJava2观察者模式的介绍 RxJava2观察者模式的使用 RxJava2的基本使用 模拟发送验证码 RxJava2与Retrofit的使用 模拟用户登陆获取用户数据 合并本地与服务器购物车列表 RxJava2与RxBinding的使用 优化搜索请求 优化点击请求 源码下载 结语 前言 作为主流的第三方框架Rx系列,不学习也不行啊,对于初学者来说,可能RxJava看起

Java计时新姿势

为获得更好的阅读体验,请访问原文:传送门 前言: 最近公司来了个大佬,从他那里学到不少东西,其中一个就是计时 的新姿势「StopWatch」,赶紧来一起了解了解吧! 一.最简单的计时 在我们的程序中不免需要对某一个运算或者方法进行计时,以便我们来观察该运算或方法是否符合我们的预期,所以在我们刚开始接触 Java 的时候都能写出类似下面这样的代码来计时: public static void main(String[] args) { Long startTime = System.current