您的位置:首页 > 编程语言

poj 1054 The Troublesome Frog 枚举+二分搜索

2016-10-25 16:35 483 查看
The Troublesome Frog

Description
In Korea, the naughtiness of the cheonggaeguri, a small frog, is legendary. This is a well-deserved reputation, because the frogs jump through your rice paddy at night, flattening rice plants. In the morning, after noting which
plants have been flattened, you want to identify the path of the frog which did the most damage. A frog always jumps through the paddy in a straight line, with every hop the same length:



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
Your program is to read from standard input. The first line contains two integers R and C, respectively the number of rows and columns in your rice paddy, 1 <= R,C <= 5000. The second line contains the single integer N, the number
of flattened rice plants, 3 <= N <= 5000. Each of the remaining N lines contains two integers, the row number (1 <= row number <= R) and the column number (1 <= column number <= C) of a flattened rice plant, separated by one blank. Each flattened plant is
only listed once.
Output
Your program is to write to standard output. The output contains one line with a single integer, the number of plants flattened along a frog path which did the most damage if there exists at least one frog path, otherwise, 0.
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


题意:

当青蛙经过农田时毁坏的稻子的痕迹是一条直线。农田里的植物就在这个农田的二维坐标系的整数格点上。如果某只青蛙经过农田,也就是某条直线穿过农田。那么那条直线经过的所有的整数格点上的植物会都被破坏掉。这些点等距的分布在这条直线上,并且必须是从外面跳进来再跳出去的,每次跳的距离相等。问根据痕迹找到一条最被破坏的最多植物的路,最多破坏多少个。

解题思路

怎么判断在一条直线上而且距离相等? x2-x1 =x3-x2 && y2-y1=y3-y2;

首先想到搜索,但是怎么搜?

如果将所有点按行序为第一要素,列序为第二要素,排序,那么排序后的坐标,后面点减前面点一定不小于0。这样枚举每个间距,如果后一个点加上这个间距得到的第三号点是被毁坏过的稻子,那么结果+1。否则后面的被毁坏的稻子更不可能满足这个间距。直接进行下一个搜索

代码

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
typedef pair <int,int> P;
const int maxn = 5000+10;
P des[maxn];
int r,c,m;//r行c列m个操作
int main()
{
int ans=0;
scanf("%d%d%d",&r,&c,&m);
for(int i=0;i<m;++i)
scanf("%d%d",&des[i].first,&des[i].second);
sort(des,des+m);
for(int i=0;i<m;++i)
{
for(int j=i+1;j<m;++j)
{
int dx = des[j].first - des[i].first;
int dy = des[j].second - des[i].second;
if(des[i].first-dx>0 && des[i].first-dx<=r && des[i].second-dy>0 && des[i].second-dy<=c) continue;
int nx = des[j].first + dx;
int ny = des[j].second + dy;
int cnt = 0;
while(nx>0&&nx<=r&&ny>0&&ny<=c)
{
P p(nx,ny);
if(binary_search(des,des+m,p)){//二分查找des中有没有first是nx,second是ny的点
cnt++;
}
else{
cnt = 0;
break;
}
nx+=dx;
ny+=dy;
}
ans=max(ans,cnt);
}
}
if(ans>0) printf("%d",ans+2);
else printf("0");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息