死亡洞穴 cave

2021-09-03 05:12:53 字數 4203 閱讀 7547

題目背景

在 caima 的 rpg 遊戲中,控制著兩個人 vv 和 jj。 這次 vv 和 jj 掉入了乙個死亡洞穴,洞穴是乙個 n*m 的矩陣。之所以稱之 為死亡洞穴,是因為在這個矩陣中有一些死亡十字。(如下圖中的+)

….+++.

.+.+.

v+.j+

由於 vv 和 jj 被分撒在了兩地,而 jj 還受了重傷,你需要讓 vv 趕到 jj 所 在的地方。為了盡量少的受死亡十字的影響,vv 要盡量遠離這些死亡十字。 我們定義洞穴中兩個格仔(x,y)和(x』,y』)之間的距離為: 也就是說,我們要使得 vv 再去找 jj 的路上,離任意死亡十字的距離都盡 可能的遠。vv 每次可以往乙個格仔的上下左右四個方向走一格。 現在你需要寫個程式,來計算最好情況下離死亡十字最近的距離。

題目描述

輸入輸出格式

輸入格式:

第一行兩個整數 n 和 m,表示矩陣規模。 接下來 n m 列,描述這個洞穴的情況。其中 v 表示 vv 所在的位置; j 表示 jj 所在的位置; . 表示空地;

表示死亡十字。

輸出格式:

一行乙個數字,表示 vv 在去找 jj 的路上,最好情況下離死亡十字最近的距 離。

輸入輸出樣例

輸入樣例

4 4+………

v…j輸出樣例3說明

對於 30% 的資料 n,m≤50。 對於 100% 的資料 n,m≤500。

看完題目感覺無從下手,在教練的一番指點後才發現這居然是一道二分答案+bfs。

思路:二分最近的十字架距離,再bfs判斷是否可以。本題考點主要在於想出二分和如何bfs。

**:

const z:array[1..4,1..2]of -1..1=((1,0),(-1,0),(0,1),(0,-1));

var i,j,k:longint;

m,n,h,t:longint;

ch:char;

fx,fy,lx,ly:longint;

l,r,mid,ans:longint;

a:array[0..501,0..501]of longint;

b,p:array[0..501,0..501]of boolean;

x,y,u:array[0..1000000]of longint;

function bfs(min:longint):boolean;//bfs也就是二分中的check

var i:longint;

begin

p:=b;

h:=1;

t:=1;

x[1]:=fx;

y[1]:=fy;

p[x[1],y[1]]:=false;

if (fx=lx) and (fy=ly) then exit(true);//可以到終點

repeat

for i:=1 to 4 do

if p[x[t]+z[i,1],y[t]+z[i,2]] and (a[x[t]+z[i,1],y[t]+z[i,2]]>=min) then//滿足距離條件

begin

inc(h);

x[h]:=x[t]+z[i,1];

y[h]:=y[t]+z[i,2];

p[x[h],y[h]]:=false;

if (x[h]=lx) and (y[h]=ly) then exit(true);

end;

inc(t);

until t>h;

exit(false);//不可以到終點

end;

begin

read(m,n);

readln;

h:=0;

t:=1;

for i:=1 to m do

begin

for j:=1 to n do

begin

read(ch);

if ch='v' then begin fx:=i; fy:=j; end;

if ch='j' then begin lx:=i; ly:=j; end;

if ch='+' then begin inc(h); x[h]:=i; y[h]:=j; b[i,j]:=false; a[i,j]:=0; u[h]:=0; end

else b[i,j]:=true;

end;

readln;

end;

p:=b;//給每個位置標記上距離,利用bfs必定先找到最優解

repeat

for i:=1 to 4 do

if p[x[t]+z[i,1],y[t]+z[i,2]] then

begin

p[x[t]+z[i,1],y[t]+z[i,2]]:=false;

inc(h);

x[h]:=x[t]+z[i,1];

y[h]:=y[t]+z[i,2];

u[h]:=u[t]+1;

a[x[h],y[h]]:=u[h];

end;

inc(t);

until t>h;

l:=1;

r:=a[fx,fy];

if a[lx,ly]如果大家不明白

給每個位置標記上距離,利用bfs必定先找到最優解

則先做一下這題:

題目描述

給出乙個n*m的01矩陣,求每個點離它最近的數字1的點的距離是多少。距離是曼哈頓距離。(平面上,座標(x1, y1)的點p1與座標(x2, y2)的點p2的曼哈頓距離為:|x1 - x2| + |y1 - y2|.)

輸入格式:

第一行兩個數n,m

後面n行,每行m個字元,為0或1

輸出格式:

共輸出n行,每行m個數,用空格分開。

輸入輸出樣例

輸入樣例

3 40001

0011

0110

輸出樣例

3 2 1 0

2 1 0 0

1 0 0 1

說明50%的資料,n,m<=100

100%的資料,n,m<=1000

這題便是上題目的乙個簡化題,題目更清晰。

**:const z:array[1..4,1..2]of -1..1=((1,0),(-1,0),(0,1),(0,-1));

var i,j,k:longint;

m,n:longint;

a:array[0..1001,0..1001]of longint;

b:array[0..1001,0..1001]of boolean;

ch:char;

h,t:longint;

x,y,u:array[0..1000000]of longint;

begin

h:=0;

t:=1;

readln(m,n);

for i:=1 to m do

for j:=1 to n do

b[i,j]:=true;

for i:=1 to m do

begin

for j:=1 to n do

begin

read(ch);

if ch='1' then//如果為1則入佇列

begin

b[i,j]:=false;

a[i,j]:=0;

inc(h);

u[h]:=0;

x[h]:=i;

y[h]:=j;

end;

end;

readln;

end;

repeat//根據bfs的性質可得第乙個找到的便是那乙個0距離最近的乙個1的距離。

for i:=1 to 4 do

if b[x[t]+z[i,1],y[t]+z[i,2]] then

begin

inc(h);

x[h]:=x[t]+z[i,1];

y[h]:=y[t]+z[i,2];

u[h]:=u[t]+1;

b[x[h],y[h]]:=false;

a[x[h],y[h]]:=u[h];

end;

inc(t);

until t>h;

for i:=1 to m do//輸出便可

begin

for j:=1 to n do write(a[i,j],' ');

writeln;

end;

end.

Sdoi2008 Cave 洞穴勘測

bzoj好了以後去交了這題,算是動態樹補完 題目大意 求一棵樹上任意兩點的連通性 這道題算是真真正正的link cut tree了,之前的動態樹題目都沒有涉及link和cut操作 所以這道題讓我發現了我在寫cut過程中的乙個錯誤,也讓我更加深刻的體會到了link cut tree的優美 對於修改,l...

逃離洞穴 escape

題意 description 小z最近出去旅遊,遇上倒霉事了。他和旅遊團一起去遊洞穴。這裡有n個洞穴,編號為1到n。它們之間,有的有雙向的小路相連,有的卻沒有,不過所有洞穴都通過小路連在了一起,沒有任何兩個洞穴不能相互到達。當遊客們分散在各處的時候,忽然出了些故障,所有燈全部熄滅。這時廣播響起,要求...

1754 逃離洞穴

基礎bfs題目的變形,在結構體裡設定答案,在狀態更新後才進行判斷。兩個基礎的bfs.include include include using namespace std intconst maxn 2000 int vis maxn maxn int rr,cc char map maxn max...