Description
Your rice paddy has plants arranged on the intersection points of a grid as shown in Figure-1, and the troublesome frogs hop completely through your paddy, starting outside the paddy on one side and ending outside the paddy on the other side as shown in Figure-2:
Many frogs can jump through the paddy, hopping from rice plant to rice plant. Every hop lands on a plant and flattens it, as in Figure-3. Note that some plants may be landed on by more than one frog during the night. Of course, you can not see the lines showing the paths of the frogs or any of their hops outside of your paddy ?for the situation in Figure-3, what you can see is shown in Figure-4:
From Figure-4, you can reconstruct all the possible paths which the frogs may have followed across your paddy. You are only interested in frogs which have landed on at least 3 of your rice plants in their voyage through the paddy. Such a path is said to be a frog path. In this case, that means that the three paths shown in Figure-3 are frog paths (there are also other possible frog paths). The vertical path down column 1 might have been a frog path with hop length 4 except there are only 2 plants flattened so we are not interested; and the diagonal path including the plants on row 2 col. 3, row 3 col. 4, and row 6 col. 7 has three flat plants but there is no regular hop length which could have spaced the hops in this way while still landing on at least 3 plants, and hence it is not a frog path. Note also that along the line a frog path follows there may be additional flattened plants which do not need to be landed on by that path (see the plant at (2, 6) on the horizontal path across row 2 in Figure-4), and in fact some flattened plants may not be explained by any frog path at all.
Your task is to write a program to determine the maximum number of landings in any single frog path (where the maximum is taken over all possible frog paths). In Figure-4 the answer is 7, obtained from the frog path across row 6.
Input
Output
Sample Input
6 7 14 2 1 6 6 4 2 2 5 2 6 2 7 3 4 6 1 6 2 2 3 6 3 6 4 6 5 6 7
Sample Output
7
解题思路:
枚举每两个被踩的水稻作为路径的起点,判断路径是否符合要求。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
struct PLANT
{
int x,y;
};
int r,c,n;
PLANT plant[5001];
PLANT pplant;
bool operator <(const PLANT &p1,const PLANT &p2){
if(p1.x==p2.x)
return p1.y<p2.y;
return p1.x<p2.x;
}
int findpath(PLANT SECplant,int dx,int dy){
int step=2;
PLANT pplant;
pplant.x=SECplant.x+dx;
pplant.y=SECplant.y+dy;
while(pplant.x<=r&&pplant.y<=c&&pplant.x>=1&&pplant.y>=1){
if(!binary_search(plant,plant+n,pplant)){
step=0;
break;
}
step++;
pplant.x+=dx;
pplant.y+=dy;
}
return(step);
}
int main()
{
int i,j,dx,dy,px,py,step,max=2;
scanf("%d %d",&r,&c);
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d %d",&plant[i].x,&plant[i].y);
sort(plant,plant+n); // 把被踩过的点排序,方便后续操作。
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++){
step=2;
dx=plant[j].x-plant[i].x;
dy=plant[j].y-plant[i].y;
px=plant[i].x-dx;
py=plant[i].y-dy;
if(px>=1&&py>=1&&px<=r&&py<=c) //如果第一步的前一步在田里,说明步长太小,第二个点需要更新
continue;
if(plant[i].x+(max-1)*dx>r) //max为当前最大步数。如果满足条件,说明步长太大,换下一个点步长只会更大,说明第一个点错了。
break;
py=plant[i].y+(max-1)*dy; //同上,判断y方向。注意dy可能为负数。
if(py<1||py>c)
continue;
step=findpath(plant[j],dx,dy);
if(step>max)
max=step;
}
if(max==2)
max=0;
printf("%d\n",max);
return 0;
}