http://gdutcode.sinaapp.com/problem.php?cid=1025&pid=3
Stubird与他的女粉丝
Description
集训队里不仅学习氛围很好,大家相处也很融洽,有一天晚上,Cloud_x1、doubleegg、wingkou和Stubird在打锄大地,Stubird一边打牌一边在想隔天跟女粉丝见面,事情是这样的,那天有n个女粉丝来找他,告诉他明天早上会在哪里等他,给他准备了礼物,但是由于粉丝太多了,Stubird不可能跟所有粉丝都见面,所以他准备隔天走一条能够见到最多女粉丝的路。我们可以把地图看成是一个二维平面,Stubird从酒店门口出发,坐标为sx,sy,他选择了一个方向,然后只能沿着那个方向一直走,规定只有Stubird面对面见到女粉丝时才能拿到她的礼物。于是,Stubird就因为这个事情,想了一晚上,所以他也洗牌洗了一晚上,他当然不服气,所以他打算报复社会,把这个问题拿来考你。
Input
第一行输入一个样例数T
下面一行有n,sx,sy,代表n(1<=n<=1500000)个女粉丝,Stubird的位置sx,sy。
下面n行每行一个坐标,代表女粉丝的坐标。坐标都是0-1000的整数
Output
Sample Input
12 1 12 23 3
Sample Output
2
由于只能往一个方向走,所以判断斜率是不可以的,因为当斜率相等的时候可能在两个相反的方向,所有可以考虑(x1-x2),(y1-y2),除以(x1-x2),(y1-y2)的最大公约数,排序处理,再将(x1-x2),(y1-y2)为0的情况特殊处理,具体看代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <queue>
#include <stack>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
#define N 4151000
#define INF 0x3f3f3f3f
#define PI acos (-1.0)
#define EPS 1e-5
#define met(a, b) memset (a, b, sizeof (a))
struct node
{
int x, y;
}p[N];
bool cmp (node a, node b)
{
if (a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
int gcd (int a, int b)
{
if (a % b == 0) return b;
return gcd (b, a%b);
}
int main ()
{
int t;
scanf ("%d", &t);
while (t--)
{
int n, sx, sy, x, y;
scanf ("%d %d %d", &n, &sx, &sy);
for (int i=0; i<n; i++)
{
scanf ("%d %d", &x, &y);
p[i].x = x - sx, p[i].y = y - sy;
if (p[i].y)
{///除以这两个数的绝对值的最大公约数
int k = gcd (abs (p[i].x), abs (p[i].y));
p[i].x /= k, p[i].y /= k;
}
}
sort (p, p+n, cmp);
int maxn = 0, cnt = 1, cnt1 = 0, cnt2 = 0, ans = 0;
if (!p[0].x && !p[0].y) ans++;
for (int i=0; i<n; i++)
{///当(y1-y2)的值为0的时候有两个方向的,s左边的是一个方向,右边的是一个方向
if (!p[i].y && p[i].x < 0) cnt1++;
if (!p[i].y && p[i].x > 0) cnt2++;
}
maxn = max (maxn, max (cnt1, cnt2));
cnt1 = 0, cnt2 = 0;
for (int i=0; i<n; i++)
{///当(x1-x2)的值为0的时候有两个方向的,s上边的是一个方向,下边的是一个方向
if (!p[i].x && p[i].y < 0) cnt1++;
if (!p[i].x && p[i].y > 0) cnt2++;
}
maxn = max (maxn, max (cnt1, cnt2));
for (int i=1; i<n; i++)
{
if (!p[i].x && !p[i].y)
{///在S所在点上,不管往哪个方向走都会收到这些粉丝的礼物
ans++;
continue;
}
if ((p[i].x == p[i-1].x && p[i].y == p[i-1].y))
cnt++;
else
{
maxn = max (maxn, cnt);
cnt = 1;
}
}
maxn = max (maxn, cnt);
if (ans == n) ans--;
printf ("%d\n", ans+maxn);
}
return 0;
}