1445 回家 推薦 的題解

2021-07-15 12:39:12 字數 3535 閱讀 8027

description

alice住在森林裡,森林可以看作是n*m的網格,森林裡有怪獸,用『.』表示空地,『+』表示怪獸,『v』表示alice現在的位置,『j』表示alice的家。

alice可以從當前單元格向上下左右相鄰單元格移動,有怪獸的地方也可以走,只不過比較危險,有怪獸的單元格對其他單元格會產生一定的危險係數,假設怪獸位置為(a,b),它對某單元格(r,c)的危險係數為:|r-a|+|c-b|,危險係數越小越危險,每個單元格的危險係數是所有怪獸對它產生的係數的最小值。

alice請你幫她找一條最佳路徑回家,即使得路徑上經過單元格的最小的危險係數最大。

input

輸入第一行包含兩個整數n和m(1<=n,m<=500),表示森林的大小。

接下來n行每行包含m個字元:『.』,『+』,『v』,『j』。

輸入只包含乙個『v』和『j』,而且至少有乙個『+』。

output

輸出最佳路徑中最小的危險係數。

一看,這題比較簡單,實際上,它是乙個運用演算法比較多的問題。

q1:處理每個單元格的危險係數

這其實就是這個題目的核心問題。

首先,我們可以把每個怪獸的位置用陣列存起來。存入乙個佇列。

對每個怪獸的位置進行寬搜。可以保證先寬搜到的必定是離怪獸最近的

為什麼?

這個時候,我們就需要嚴謹的證明了。

寬蒐時,我們都是有乙個當前步驟的原點,引申出來的。

舉個例子:當前寬搜到第五步,那麼第五步寬搜到的只有第六步的點。

因此, 可以保證 先寬搜到的必定是離怪獸最近的。

我們現在把這乙個定理姑且叫做「寬搜定理。」

解決了第乙個問題之後,我們又遇到了第二個問題:

q2:怎麼讓那個alice走對路

我們開始進入到這個題目的第二個核心的問題(也就兩個問題)

首先,我們必須要了解的是:第二個問題不滿足「寬搜定理」。

為什麼?

因為可能你繞路走的危險係數比直走還小呢!

那我們該怎麼辦?

binary search!

我們可以二分答案。然後驗證答案是否可行。

比如說我們現在二分到乙個3的危險度(也就是說這條路上的危險係數不可以小於三,

危險係數越小越危險

寬蒐時,我們應該多加乙個條件:目標格仔的危險度不可以小於二分值。

於是問題就迎刃而解了。

var

i,j,k,n,s,t,m,s1,s2,h1,h2:longint;

d:array[0..1000000,1..3]of longint;

f:array[0..1000000,1..2]of longint;

c:array[0..1000,0..1000]of char;

data:array[0..1000,0..1000]of longint;

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

l,r,x:longint;

bj:array[0..1000,0..1000]of boolean;

procedure work;

var i,j,k,x,y:longint;

begin

fillchar(bj,sizeof(bj),0);

fillchar(d,sizeof(d),0);

for i:=1 to f[0,1] do

begin

d[i,1]:=f[i,1];

d[i,2]:=f[i,2];

d[i,3]:=0;

bj[f[i,1],f[i,2]]:=true;

data[f[i,1],f[i,2]]:=0;

end;

i:=0;

j:=f[0,1];

while i0)and(x<=n)and(y>0)and(y<=m) then

begin

inc(j);

d[j,1]:=x;

d[j,2]:=y;

d[j,3]:=d[i,3]+1;

data[x,y]:=d[j,3];

bj[x,y]:=true;

end;

end;

end;

end;

end;

function prepare(t:longint):boolean;

var i,j,k,x,y:longint;

begin

fillchar(bj,sizeof(bj),false);

fillchar(d,sizeof(d),false);

i:=0;

j:=1;

d[1,1]:=s1;

d[1,2]:=s2;

bj[s1,s2]:=true;

while i0)and(x<=n)and(y>0)and(y<=m)and(data[x,y]>=t) then

begin

inc(j);

d[j,1]:=x;

d[j,2]:=y;

bj[x,y]:=true;

end;

end;

end;

end;

exit(false);

end;

begin

fillchar(data,sizeof(data),$7f);

readln(n,m);

for i:=1 to n do

begin

for j:=1 to m do

begin

read(c[i,j]);

if c[i,j]='+' then

begin

inc(f[0,1]);

f[f[0,1],1]:=i;

f[f[0,1],2]:=j;

end;

if c[i,j]='j' then

begin

h1:=i;

h2:=j;

end;

if c[i,j]='v' then

begin

s1:=i;

s2:=j;

end;

end;

readln;

end;

work;

l:=0;

r:=data[s1,s2];

//writeln(data[s1,s2]);

while l<=r do

begin

x:=(l+r) div 2;

if prepare(x) then l:=x+1

else r:=x-1;

end;

writeln(l-1);

end.

謝謝你的大力支援!

NOI題解DAY1 1 回家路線

於我而言,今年的noi簡直殺人。即使我只考了第一天,我就崩潰了。還是我太菜,我自己而言,我最多得五分不能再多了。後來交了 確實只有五分。反正大家知道我菜就對了。有 n 個點和 m 趟列車,第 i 輛列車於 pi 時刻從 xi 號點出發,於 qi 時刻到達 yi 號點。有乙隻小貓要從 1 號點坐車到 ...

P3831 SHOI2012 回家的路 題解

題目傳送門 解法 1 每兩個點都連邊,跑裸的最短路。顯然,n 和 m 非常大,暴力連邊會 tle 和 mle。解法 2 正解 首先,對答案產生貢獻的只有換乘站,所以我們只用連兩種邊 乙個換乘站看作 2 個節點,連邊,邊權為 1 站內換乘 將 x 相等的換乘站相連,y 相等的換乘站相連。其中,起點和終...

題解 P3831 SHOI2012 回家的路

什麼叫分層圖最短路,我不會 kk 感覺自己做法和其他題解不大一樣所以過來發篇題解了。未刻意卡常拿下最優解 就是說給你乙個 n times n 的網格圖和 m 個可換乘點,然後你只能在同一行或同一列 如果在行上移動,就不能在列上移動 反之同理 上移動,除非這個點是可以換乘的。每次走一格花費 2 費,換...