問題描述
在南韓,有一種小的青蛙。每到晚上,這種青蛙會跳越稻田,從而踩踏稻子。農民在早
上看到被踩踏的稻子,希望找到造成最大損害的那只青蛙經過的路徑。每只青蛙總是沿著一
條直線跳越稻田,而且每次跳躍的距離都相同,如圖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 #includetypedef
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 棵...