zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 41 (Rated for Div. 2) D. Pair Of Lines (几何,随机)

    D. Pair Of Lines

    time limit per test

    2 seconds

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    You are given n points on Cartesian plane. Every point is a lattice point (i. e. both of its coordinates are integers), and all points are distinct.

    You may draw two straight lines (not necessarily distinct). Is it possible to do this in such a way that every point lies on at least one of these lines?

    Input

    The first line contains one integer n (1 ≤ n ≤ 105) — the number of points you are given.

    Then n lines follow, each line containing two integers x**i and y**i (|x**i|, |y**i| ≤ 109)— coordinates of i-th point. All n points are distinct.

    Output

    If it is possible to draw two straight lines in such a way that each of given points belongs to at least one of these lines, print YES. Otherwise, print NO.

    Examples

    input

    Copy

    50 00 11 11 -12 2
    

    output

    Copy

    YES
    

    input

    Copy

    50 01 02 11 12 3
    

    output

    Copy

    NO
    

    Note

    In the first example it is possible to draw two lines, the one containing the points 1, 3 and 5, and another one containing two remaining points.

    img

    题意:

    给你n个坐标点

    问你能不能画两条直线,使所有的点都落在直线上。

    (两条直线可以重合)。

    思路:

    n<=4 直接输出YES

    n>=5 时,我们这样考虑:

    如果这n个点是满足条件的。

    那么两条线上点数中较大的那一个(称为L1)一定大于等于n/2

    所以我们可以随机从n个点中选择2个点。

    这两点同时落在L1上的概率为(1/4)

    所以如果这n个点满足条件,我们只需要随机大概4次就可以找到那两条线。

    4次只是期望值,N的数据范围是(1e5) 所以我们可以随机50次以上,这样更稳。

    关于随机到2个点,

    我们扫一遍数组,把所有不在这2个确定的直线上的都扔在一个vector里存着。

    然后我们再判断vector中所有点是否在同一个直线上。如果有满足条件的就结束随机,输出Yes。

    代码:

    #include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    // #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    
    inline void getInt(int *p);
    const int maxn = 100010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    const double eps = 1e-6;
    int sgn(double x)
    {
        if (fabs(x) < eps) { return 0; }
        if (x < 0) { return -1; }
        else { return 1; }
    }
    struct Point {
        ll x, y;
        Point() {}
        Point(double _x, double _y)
        {
            x = _x; y = _y;
        }
        void input()
        {
            cin >> x >> y;
        }
        Point operator -(const Point &b)const
        {
            return Point(x - b.x, y - b.y);
        }
    
        // 111 / 179
    //叉积
        double operator ^(const Point &b)const
        {
            return x * b.y - y * b.x;
        }
    //点积
        double operator *(const Point &b)const
        {
            return x * b.x + y * b.y;
        }
    //绕原点旋转角度 B(弧度值),后 x,y 的变化
        void transXY(double B)
        {
            double tx = x, ty = y;
            x = tx * cos(B) - ty * sin(B);
            y = tx * sin(B) + ty * cos(B);
        }
    };
    int n;
    Point a[maxn];
    std::vector<int> p;
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        gbtb;
        cin >> n;
        repd(i, 1, n) {
            a[i].input();
        }
        if (n <= 4) {
            cout << "YES" << endl;
            return 0;
        }
        int id1, id2;
        mt19937 rnd(time(0));
        int isok = 0;
        repd(rp, 1, 100) {
            p.clear();
            id1 = rnd() % n + 1;
            do {
                id2 = rnd() % n + 1;
            } while (id2 == id1);
            repd(i, 1, n) {
                if (i == id1 || id2 == i) {
                    continue;
                }
                if (((a[id2] - a[id1]) ^ (a[i] - a[id1])) != 0) {
                    p.push_back(i);
                }
            }
            int flag = 1;
            for (int i = 2; i < sz(p); ++i) {
                if (((a[p[1]] - a[p[0]]) ^ (a[p[i]] - a[p[0]])) != 0) {
                    flag = 0;
                    break;
                }
            }
            if (flag) {
                isok = 1;
    //            chu(id1);
    //            chu(id2);
                break;
            }
        }
        if (isok) {
            cout << "YES" << endl;
        } else {
            cout << "NO" << endl;
        }
        return 0;
    }
    
    inline void getInt(int *p)
    {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        } else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    移动端屏幕旋转的事件和样式方案。
    active:移动端触摸按钮的效果。
    移动端字体单位该使用px还是rem?
    Cordova/Ionic Android 开发环境搭建
    JavaScript 深拷贝(deep copy)和浅拷贝(shallow copy)
    你不知道的JS之 this 和对象原型(一)this 是什么
    你不知道的JS之作用域和闭包 附录
    你不知道的JS之作用域和闭包(五)作用域闭包
    你不知道的JS之作用域和闭包(四)(声明)提升
    你不知道的JS之作用域和闭包(三)函数 vs. 块级作用域
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11852880.html
Copyright © 2011-2022 走看看