• 2021“MINIEYE杯”中国大学生算法设计超级联赛 1004. Game on Plane(几何)


    Problem Description

    Alice and Bob are playing a game. In this game, there are n straight lines on the 2D plane. Alice will select exactly k straight lines l1,l2,…,lk among all the n straight lines first, then Bob will draw a straight line L. The penalty of Bob is defined as the number of lines in {l1,l2,…,lk} that shares at least one common point with L. Note that two overlapping lines also share common points.

    Alice wants to maximize the penalty of Bob while Bob wants to minimize it. You will be given these n lines, please write a program to predict the penalty of Bob for k=1,2,3,…,n if both of the players play optimally.

    Input

    The first line contains a single integer T (1≤T≤500), the number of test cases. For each test case:

    The first line contains a single integer n (1≤n≤100000), denoting the number of straight lines.

    Each of the next n lines contains four integers xai,yai,xbi and ybi (0≤xai,yai,xbi,ybi≤109), denoting a straight line passes both (xai,yai) and (xbi,ybi). (xai,yai)will never be coincided with (xbi,ybi).

    It is guaranteed that the sum of all n is at most 1000000.

    Output

    For each test case, output n lines, the i-th (1≤i≤n) of which containing an integer, denoting the penalty of Bob when k=i.

    Sample Input

    2
    2
    1 1 2 2
    0 0 2 3
    3
    1 1 2 2
    1 1 2 2
    3 2 5 4
    

    Sample Output

    0
    1
    0
    0
    0
    

    题意是Alice提前给出n条直线,然后Alice不断从中任意选择1、2...n条直线,使得以最优策略作一条直线后新的直线与选出来的直线交点数最多。

    首先把n条直线读进来,分别求出每种斜率对应多少条直线,斜率可以用结构体存(本身就是y2 - y1与x2 - x1的比值,注意要用gcd进行约分),维护数目可以用map。然后遍历map把这些数目从大到小排序,每次尽可能选不一样的斜率即可。

    注意特判斜率不存在的情况!以及要处理斜率为负的情况(可以把负号给第一个元素)

    #include<bits/stdc++.h>
    typedef long long ll; 
    #define int long long
    using namespace std;
    int gcd(int a, int b) {
        return b ? gcd(b, a % b) : a;
    }
    signed main(){
        int T;
        scanf("%lld",&T);
        while(T--){
            int n;
            scanf("%lld",&n);
            map<pair<int,int>,int> mp;
            int x1,y1,x2,y2,x,y;
            for(int i=0;i<n;i++){
                scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
                x=x2-x1,y=y2-y1;
                bool flag = ((x < 0) ^ (y < 0));
                if(x < 0) x = -x;
                if(y < 0) y = -y;
                int comm=gcd(x,y);
                if(flag) x = -x;
                pair<int,int> p;
                if(x1 == x2) {//斜率不存在
                    p = make_pair(0,1);
                } else if(y1 == y2) {//斜率为0
                    p = make_pair(1,0);
                } else p = make_pair(x/comm,y/comm);
                if(!mp[p]){ mp[p]=1;}//维护p这种斜率对应的数目
                else mp[p]++;
            } 
            map<pair<int, int>, int>::iterator it;
            vector<int> v;
            for(it = mp.begin(); it != mp.end(); it++) {
                v.push_back(it->second);
            }
            sort(v.begin(), v.end(), greater<int>());
            int len = v.size();
            int pos = 0;
            int round = 0;//一趟趟遍历
            for(int i = 1; i <= n; i++) {
                if(!v[pos] || pos == len) pos = 0, round++;//当前这种已经用光了或者遍历到头了,直接进行下一轮
                printf("%lld
    ", i - round - 1);
                v[pos]--;//用一种
                pos++;
            }
        } 
        return 0;
    }
    // 1
    // 6
    // 1 2 3 4
    // 1 2 3 4
    // 9 8 7 600
    // 1 10 2 9
    // 1 1001 900 800
    // 5 9 1 3
    
    
    // 5
    // 5
    // 0 0 1 1
    // 1 1 0 0
    // 0 0 1 1
    // 1 2 3 9
    // 3 9 1 2
    
  • 相关阅读:
    设计模式:生产者消费者模式
    图解SSH原理
    监听Google Player下载并获取包名等信息
    android targetSdkVersion>=26收不到广播的处理
    ant property file刷新不及时
    maven的pom文件报错: must be "pom" but is "jar"
    AJAX其实就是一个异步网络请求
    String、StringBuffer、StringBuilder的区别
    Properties、ResourceBundle
    JavaWeb--Listener
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/15068437.html
Copyright © 2020-2023  润新知