Time Limit:2s Memory Limit:64MByte
Submissions:584Solved:220
You are the god of cars, standing at (a, b) point.There are some cars at point (xi,yi)(xi,yi). If lots of cars and you are in one line, you can only see the car that is nearest to yourself. How many cars can you see?
It is guaranteed that xi>axi>a and yi>byi>b.
开始的时候你站在点(a,b),现在有很多人站在不同的点(xi,yi),只在点 (a,b)的右上方,即 (xi>a and yi>b),你要观察有多少个人,假设有很多人在一排中,你只能看到一个人,现在问你能够看到多少人。
解题思路:
我们现在来分析一下,如果想站到一排中的话,他们的斜率必然是相等的,那么我们可以计算这样的一个点 (x,y)保证的是(x,y) 点是互素的,Eg: (1,1) , (2,2), (3,3) 这样的点都是一样的,那么我们只需要取 (1,1) 点就 OK 了,那么我们就定义一个含有 (x,y) 的一个结构体,那么我们要求的就是这个结构体的元素的个数就行了,那么很容易就想到用集合set 来 操作,因为 set 自带去重的功能,我们只需要对其内部的排序方法 < 进行重载就行了。然后就是计算了,把 (a,b) 当成原点,然后求一下 (xi, yi) 的 最大公约数 d ,然后 P(xi/d,yi/d) ,将 P 扔进 set 中,最后输出 set.size();
My Code:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <cstdlib>
#include <set>
using namespace std;
typedef long long LL;
int GCD(int a, int b){
if(b == 0)
return a;
return GCD(b, a%b);
}
struct Point{
int x, y;
/**一定要有这个,要不然报错**/
bool operator<(const Point & a)const{
if(a.x == x)
return a.y < y;
return a.x < x;
}
}p;
set<Point> se;
int main()
{
int T;
scanf("%d",&T);
while(T--){
int a, b, n, x, y;
se.clear();
scanf("%d%d%d",&a,&b,&n);
for(int i=0; i<n; i++){
scanf("%d%d",&x,&y);
x -= a, y -= b;
int d = GCD(x,y);
x /= d, y /= d;
p.x = x, p.y = y;
se.insert(p);
}
printf("%d\n",se.size());
}
return 0;
}