討厭的青蛙

2021-09-07 21:56:29 字數 3581 閱讀 1549

問題描述

在南韓,有一種小的青蛙。每到晚上,這種青蛙會跳越稻田,從而踩踏稻子。農民在早

上看到被踩踏的稻子,希望找到造成最大損害的那只青蛙經過的路徑。每只青蛙總是沿著一

條直線跳越稻田,而且每次跳躍的距離都相同,如圖8-4 所示。 稻田裡的稻子組成乙個柵

格,每棵稻子位於乙個格點上,如圖8-5 所示。而青蛙總是從稻田的一側跳進稻田,然後沿

著某條直線穿越稻田,從另一側跳出去,如圖8-6 所示。

青蛙的每一跳都恰好踩在一棵水稻上,將這棵水稻拍倒。可能會有多隻青蛙從稻田穿越,

有些水稻被多隻青蛙踩踏,如圖8-7 所示。當然,農民所見到的是圖8-8 中的情形,看不到

圖8-7中的直線。

根據圖8-8,農民能夠構造出青蛙穿越稻田時的行走路徑,並且只關心那些在穿越稻田

時至少踩踏了3 棵水稻的青蛙。因此,每條青蛙行走路徑上至少包括3 棵被踩踏的水稻。而

在一條青蛙行走路徑的直線上,也可能會有些被踩踏的水稻不屬於該行走路徑。在圖8-8 中,

格點(2, 1)、(6, 1)上的水稻可能是同一只青蛙踩踏的,但這條線上只有兩棵被踩踏的水稻,

因此不能作為一條青蛙行走路徑;格點(2, 3)、(3, 4)、(6, 6)在同一條直線上,但它們的間距

不等,因此不能作為一條青蛙行走路徑;格點(2, 1)、(2, 3)、(2, 5)、(2, 7)是一條青蛙行走路

徑,該路徑不包括格點(2, 6)。請你寫乙個程式,確定在所有的青蛙行路徑中,踩踏水稻棵

數最多的路徑上有多少棵水稻被踩踏。例如,圖8-8 的答案是7,因為第6 行上全部水稻恰

好構成一條青蛙行走路徑。

輸入資料

從標準輸入裝置上讀入資料。第一行上兩個整數r、c,分別表示稻田中水稻的行數和

列數,1≤r、c≤5000。第二行是乙個整數n,表示被踩踏的水稻數量, 3≤n≤5000。在剩下

的n 行中,每行有兩個整數,分別是一顆被踩踏水稻的行號(1~r)和列號(1~c),兩個整數用

乙個空格隔開。而且,每棵被踩踏水稻只被列出一次。

輸出要求

從標準輸出裝置上輸出乙個整數。如果在稻田中存在青蛙行走路徑,則輸出包含最多水

稻的青蛙行走路徑中的水稻數量,否則輸出0。

輸入樣例

6 714

2 16 6

4 22 5

2 62 7

3 46 1

6 22 3

6 36 4

6 56 7

輸出樣例

7我的解題思路:

根據條件,必須在田裡跳三跳以上的路徑才算路徑。我們就可以求出他們的每一跳的區間必須小於等於總行(列)數除以三。然後以這個區間內的數去跳,使用遞迴去搜尋每種情況,以為它們總是沿著直線跳,那麼遞迴裡面的改變值是固定的,所以程式裡面要把jump的i,j固定。這樣才能搜尋出是直線的。對於搜尋,我是對每個可能的點發散它的四周去搜尋,那麼這樣會出現很多重複的情況。不過似乎我的程式還是有點問題。因為它只從邊上跑進去,那麼必須是進去又出來了。那麼我沒考慮周全。。。我再去看看別人給出的答案吧。

#include #define max 5001

intnmax;

intnarr[max][max];

intnrow,ncol,ncount,ntimes;

void

output()

printf("\n

");}

}void jump(int row,int col,int i,int

j)

else

return

; }

}int

main()

}fscanf(fp,"%d

",&ncount);

while

(ncount)

output();

nrowzone = nrow/3

; ncolzone = ncol/3

;

for (r=1; r<=nrow; r++)

else

if( narr[r][c] && 1

<=r+i && r+i<=nrow && 1

<=c+j && c+j<=ncol && narr[r+i][c+j])}}

}}printf(

"%d\n

",nmax);

return0;

}2013/4/29 21:52

題後感:看過別人的方法後,我發現了自己的問題。首先,只用乙個二維陣列來做的話,太大,而且不好做搜尋,其實比較好的方法是構造乙個資料結構來儲存。其次,一開始就沒有想到可以尋找任意兩個節點,然後計算出步長,再去判斷能否構成乙個路徑,這才是對這道題正確並高效的解題方法。在比較任意兩個節點的時候,我們還可以先對節點按行先進行排列,這樣就可以做到任意乙個點與它後面的每個點來比較,這樣可以避免重複。

這題我覺得主要還是要會判斷條件方面,要考慮周全,不然就會tle。還有就是要判斷不存在的情況。同時學會運用qsort和bsearch函式。

#include #include 

typedef

struct

plantplants;

plants plants[

5001

];int

row,col,n;

int mycmp(const

void *p1, const

void *p2)

int searchpath(plants p, int x, int

y) steps++;

plant.r = plant.r +x;

plant.c = plant.c +y;

}return

steps;

}int

main()

qsort(plants,n,

sizeof

(plants),mycmp);

for(i=0; i2; i++)

//下面這兩個if條件是判斷下一步是不是在稻田裡,不在的話就不用考慮了

if ((plants[i].c + max*dy < 1) || (plants[i].c + max*dy >col))

if (plants[i].r + max*dx >row)

steps =searchpath(plants[j],dx,dy);

max = max>steps?max:steps;}}

if (max == 2) max=0

; printf(

"%d\n

",max);

return0;

}2013/4/30 19:29

討厭的青蛙

題目很長,直接放鏈結討厭的青蛙 要求出最長的路徑,就要比較所有的路徑長度。對於每一條路徑,因為步長相等,所以只要確定開始兩個被踩的點就可以求出整條路徑了。假設前兩個點為 x1,y1 x2,y2 則步長dx x2 x1,dy y2 y1,需要判斷下面三個條件是否都滿足。之後的每個點 xi,yi x i...

演算法題 討厭的青蛙

青蛙問題,求解一條路徑 這條路徑中被乙隻青蛙壓倒的稻子最多 青蛙只會在乙個方向上前進,並且步長是一定的 include include include using namespace std int r,c,n struct plant 記錄被踩壞的水稻座標 為了debug方便自己先初始化 plan...

poj 1054 討厭的青蛙

這個問題看起來很複雜,其實目的很簡單 幫助農民找到為害最大的青蛙。也就是要找到 一條穿越稻田的青蛙路徑,這個路徑上被踩踏的水稻不少於其他任何青蛙路徑上被踩踏的水 稻數。當然,整個稻田中也可能根本就不存在青蛙路徑。問題的關鍵是 找到穿越稻田的全 部青蛙路徑。任何一條穿越稻田的青蛙路徑l,至少包括3 棵...