玲珑杯1052 - See car——STL集合的应用(“玲珑杯”ACM比赛 Round #4 )

传送门

1052 - See car

Time Limit:2s Memory Limit:64MByte

Submissions:584Solved:220

DESCRIPTION

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.

INPUT
There are multiple test cases.The first line is a number T (T  11 ≤11), which means the number of cases.For each case, first line has three integers a,b,n(109a,b109,0n105)a,b,n(−109≤a,b≤109,0≤n≤105).next nn lines, each line contains two integer (xi,yi)(109xi,yi109)(xi,yi)(−109≤xi,yi≤109), which means the position of car.
OUTPUT
one line --- the number of car that you can see.
SAMPLE INPUT
20 0 31 1 2 23 30 0 41 12 22 34 6
SAMPLE OUTPUT
12
题目大意:


开始的时候你站在点(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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值