2018 9 4南海中學測試T1

2021-08-27 08:58:09 字數 2354 閱讀 5966

田野上搭建了乙個**大神專用的柵欄圍成的迷宮。幸運的是,在迷宮的邊界上留出了兩段柵欄作為迷宮的出口。更幸運的是,所建造的迷宮是乙個「完美的」迷宮:即你能從迷宮中的任意一點找到一條走出迷宮的路。給定迷宮的寬w(1<=w<=38)及長h(1<=h<=100)。 2*h+1行,每行2*w+1的字元以下面給出的格式表示乙個迷宮。然後計算從迷宮中最「糟糕」的那乙個點走出迷宮所需的步數(就是從最「糟糕」的一點,走出迷宮的最少步數)。(即使從這一點以最優的方式走向最靠近的出口,它仍然需要最多的步數)當然了,**大神讓你必須只會水平或垂直地在x或y軸上移動,你不能從來不走對角線。每移動到乙個新的方格算作一步(包括移出迷宮的那一步)這是乙個w=5,h=3的迷宮:

如上圖的例子,柵欄的柱子只出現在奇數行或奇數列。每個迷宮只有兩個出口。

program name: maze

input format: (file maze.in)

第一行: w和h(用空格隔開)

第二行至第2*h+1行: 每行2*w+1個字元表示迷宮

output format: (file maze.out)

輸出乙個單獨的整數,表示能保證牛從迷宮中任意一點走出迷宮的最小步數。

9題目很容易看懂,每個點到最近的出口都有乙個最短路徑,那麼就求出所有點走出最近出口的最短路徑的最大值。那麼想法很簡單,直接兩個bfs就ok了。每次bfs儲存走到這個格仔的最小值,跑完兩次之後找最大值就可以了。

然後這道題目和其他題目不同的是,它的圖很奇怪,並不是經常見到的01圖。觀察這個圖可得知,其實w一共有2*w+1這麼大, h也只是有2*h+1這麼大。然後奇數行都是牆,都不是能走的格仔。還有乙個最重要的問題,這個圖之中還有空格。這個讓我們儲存這個圖有一點難度。

所以我就像下面**一樣儲存這個圖:

for(int i=1;i<=h;i++)

}

每次讀入乙個字元,用getchar()不僅能讀入空格,也能讀入換行符。所以在讀入完每一行的資料之後都要getchar()一下。然後就判斷讀入的是否是空格就ok了。

然後就是儲存出口的問題了。這道題我一開始爆零就是因為找出口太片面了,認為出口肯定乙個在上下,乙個在右,所以兩次bfs前現在上下找乙個出口,或者在左右找乙個出口。

這樣明顯是錯誤的嘛,所以找出口在輸入的時候加上一條判斷,如果是出口就儲存,那就ok啦。

if((i==1)&&(x==' ')) 

if((i==h)&&(x==' '))

if((j==1)&&(x==' '))

if((j==w)&&(x==' '))

然後我在我錯誤的程式上修改後,測試完有乙個點總是超時。而且這個圖也是特別的奇葩。

這個圖超級帥,超有規律,但是我就是超時了。比這個資料還大的資料我都不超時,就這個超時了。然後我除錯的時候發現,我在bfs時死迴圈了。然後我看了很久,才發現我犯了乙個錯誤,而且這個錯誤在我寫bfs時也是很常見。

大家先看看我錯誤的bfs:

void bfs()}}}}}

先解釋一下,能走的格仔之間是有牆的,所以先判斷距離為一的地方是否時牆,如果不是牆表示能走,所以就走兩步,這是由於這道題才這麼做的。

回歸正題,那麼這個bfs看上去沒錯的,但是導致了死迴圈,為什麼呢?

看看我vis陣列,標記的位置是在當執行到這個點的時候才標記為true。那麼就會出現乙個情況,我很多個點都能重複走到乙個點,那麼我這個點就一直入隊,一直入一直入,所以導致了死迴圈。

解決辦法很簡單,當發現這個可以走時直接標記為true,這樣就不會出現這種重複入隊的情況了。

void bfs()}}}}}

這個就是完美的bfs了。

這道題給我最大的教訓吧,就是bfs標記的問題了,希望自己能夠記住這個教訓。

2018 10 20測試T1 蛋糕

內網傳送門 外網傳送門 我們先對於 a 排序,然後對於 b,其實就是求上公升序列最少有多少個 還是乙個很常見的模型吧,記錄乙個陣列,每次加入乙個點的時候,就找它前驅的位置,更新一下就可以了 然後求它屬於哪個蛋糕就直接再開乙個陣列記錄一下 應該是一道水題吧。include include includ...

2018 10 16測試T1 膜法

內網傳送門 外網傳送門 做這道題之前,先儲備一些關於組合數的知識吧 c nm cnn m c n m c n cnm c nn m cn m cn 1m cn 1 m 1c n m c m c cnm c n 1m cn 1m 1 c n0 cn1 cn2 cnn 2 nc n 0 c n 1 c ...

2019 07 25測試 T1 中位數

傳送門 給你乙個長度為 n nn 的正整數序列 它包含 2n 1 2 n 1 2n 1 個非空子序列,注意到 2n 1 2 n 1 2n 1 是乙個奇數。我們定義乙個子串行的權值為子串行內所有元素權值之和,求所有非空子序列的權值的中位數。資料範圍 1 n 2000 1 n 2000 1 n 20 0...