解題思路:因為要求出最長的路徑,所以需要比較全部的路徑長度。對於每一條路徑,因為步長相等,所以只要確定開始兩個被踩的點就可以求出整條路徑。假設前兩個點為(x1,y1),(x2,y2),則步長為dx=x2-x1,dy=y2-y1,需要判斷下面三個條件是否都滿足。
(1)之後每個點(xi,yi)=(xi-1+dx,yi-1+dy)=(x2+(i-2)*dx,y2+(i-2)*dy),要依次判斷各個點是否被踩過。
(2)(x1-dx,y1-dy)需要落在稻田之外。
(3)將路徑上的最後一棵水稻記作(xk,yk),則(xk+dx,yk+dy)需要落在稻田之外。
因此,程式只要分別列舉前兩個點,然後判斷整條路徑是否存在並判斷長度是否大於當前最大值即可。判斷乙個點是否被踩過時,可以用乙個布林矩陣。布林矩陣中一開始就存好各個點的狀態,true表示被踩過,false表示未被踩過,這樣之後判斷時可以用o(1)的效率確定乙個點是否被踩過。
由於時限要求,實現時要注意一些條件的判斷,以提高效率。例如,當下列條件之一滿足時,當前列舉的兩個點的路徑就不滿足最長路徑。
(1)青蛙不能經過一跳從稻田外跳到(x1,y1)上(此時一定不滿足條件)。
(2)按照(x1,y1),(x2,y2)確定的步長,從(x1,y1)出發,青蛙經過(maxsteps-1)步,就會跳到稻田之外,其中maxsteps是當前已經找到的最好答案(此時即使滿足條件,答案也不會更優)。
#include#include#includeusing namespace std;
#define maxn (5000+10)
struct point;
int r,c;
int n;
int ans=0;
bool flag[maxn][maxn];
point p[maxn];
bool operator
//判斷以點a和b為起點的路徑是否存在
bool count(int a,int b)
if(outside(x1,y1)&&k>ans)ans=k;
}int main()
sort(p,p+n); //將點排序,注意這裡過載了point的《運算子
for(int i=0;i
for(int j=i+1;j
count(i,j); //列舉每一種情況
if(ans<3) ans=0;
printf("%d\n",ans);
return 0;
}
poj 2812 惱人的青蛙(列舉 剪枝)
程式設計實習列舉練習 poj 2812 惱人的青蛙 列舉 剪枝 總時間限制 2000ms 單個測試點時間限制 500ms 記憶體限制 65536kb 描述 在南韓,有一種小的青蛙。每到晚上,這種青蛙會跳越稻田,從而踩踏稻子。農民在早上看到被踩踏的稻子,希望找到造成最大損害的那只青蛙經過的路徑。每只青...
2812 惱人的青蛙
總時間限制 2000ms 單個測試點時間限制 500ms 記憶體限制 65536kb 描述在南韓,有一種小的青蛙。每到晚上,這種青蛙會跳越稻田,從而踩踏稻子。農民在早上看到被踩踏的稻子,希望找到造成最大損害的那只青蛙經過的路徑。每只青蛙總是沿著一條直線跳越稻田,而且每次跳躍的距離都相同。如下圖所示,...
poj 1054 討厭的青蛙
這個問題看起來很複雜,其實目的很簡單 幫助農民找到為害最大的青蛙。也就是要找到 一條穿越稻田的青蛙路徑,這個路徑上被踩踏的水稻不少於其他任何青蛙路徑上被踩踏的水 稻數。當然,整個稻田中也可能根本就不存在青蛙路徑。問題的關鍵是 找到穿越稻田的全 部青蛙路徑。任何一條穿越稻田的青蛙路徑l,至少包括3 棵...