CF EDU 41 D 题 Pair Of Lines 【经典几何题】

传送门
题意: 给定n个二维平面上的点, 问这些点是否存在于两条直线上.. (如果还对题意比较迷, 那就再说一种那就是所有点共线时也是YES)

思路: 首先, 如果点数<3, 很明显是YES, 所以当点数大于3时我们只需要对前面三个点进行判断就是了, 假设以第一个点和第二个点确定一条直线, 此时我们先把在这条直线上的点先去除, 可以利用向量来判断三点是否共线, 很方便. 然后判断剩下的点是否能构成另一条直线即可, 如果不仅能再去判断第一个和第三个, 第二个和第三个, 以同样的方法….. 注意看清楚题意!…
具体细节请看代码实现.

AC Code

const int maxn = 1e5+5;
struct point {
    int x, y;
}p[maxn];
int n;
bool vis[maxn];
point operator - (const point &a, const point &b) {
    return point{a.x - b.x, a.y - b.y};
}

ll corss(point a, point b) {
    return 1ll*a.x * b.y - 1ll*b.x * a.y;
}

bool check() {
    int p1 = -1, p2 = -1;
    for (int i = 1 ; i <= n ; i ++) {
        if (vis[i]) continue;
        if (p1 == -1) p1 = i;
        else if (p2 == -1) p2 = i;
    }
    if (p2 == -1) return true;
    for (int i = 1 ; i <= n ; i ++) {
        if (vis[i]) continue;
        if (corss(p[p1] - p[p2], p[i] - p[p1])) return false;
    }
    return true;
}
bool ok(point a, point b) {
    Fill(vis, 0);
    for (int i = 1 ; i <= n ; i ++) {
        if (!corss(b - a, p[i] - a)) vis[i] = 1;
    }
    return check();
}
void solve()
{
    while(~scanf("%d", &n)) {
        for (int i = 1 ; i <= n ; i ++) {
            scanf("%d%d", &p[i].x, &p[i].y);
        }
        if (n < 3) {
            printf("YES\n");
            continue ;
        }
        if (ok(p[1], p[2]) || ok(p[1], p[3]) || ok(p[2], p[3]))
            printf("YES\n");
        else printf("NO\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值