• 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/ 希望所写的文章对您有帮助。
  • 相关阅读:
    在idea的控制台进行git pull 或者git push的时候每次都要输入用户名和密码的解决办法
    js中和html中onclick绑定函数要不要加括号的问题
    ElementUI checkbox组件中的indeterminate 状态
    js之常见问题--for循环中为什么点击总是弹出最后一个i
    vue中watch监听浏览器窗口大小的改变
    Duplicate keys detected: '0'. This may cause an update error.
    数组对象去重总结
    【转载】git 回退版本
    K8s
    go 记录日志到Elk
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11852880.html
Copyright © 2020-2023  润新知