hdu3 1004 Game On Plane

21 篇文章 0 订阅

题意:Alice和Bob正在玩游戏,在这个游戏中,2d平面上共有n条直线。Alice会在所有 n 条直线中选择 k 条直线 l1、l2、…、lk,然后Bob将绘制额外的一条直线 L。对 Bob 的惩罚定义为 L 与Alice选择的 k 条直线有交点的直线的数量。(请注意,两条重叠线也算有交点。)
Alice想最大化对 Bob 的处罚,而 Bob 想最小化处罚。你将得到这n行,请编写一个程序来预测当 k = 1, 2, 3,…,n时,如果两个玩家都发挥最佳状态,求Bob 的惩罚。
输入描述:
第一行包含一个整数T(1 ≤ T ≤ 500),表示测试用例的数量。对于每个测试用例:第一行包含一个整数 n(1 ≤ N ≤ 100000),表示直线的数量。接下来的n行中的每一行都包含四个整数xai、yai、xbi和ybi(0 ≤ xai,yai,xbi,ybi ≤ 10^9),表示一条直线同时经过(xai,yai)和(xbi,ybi)((xai,yai)永远不会与(xbi,ybi)重合,保证所有n的总和不超过1000000。)
输出描述:
对于每个测试用例,输出 n 行,第 i 行(1 ≤ i ≤ n) 其中包含一个整数,表示 k = i 时Bob的惩罚。

思路:Alice 会从n条直线中优先选择斜率不同的直线,使得k条直线中尽可能少的直线平行,Bob 所画的直线 L 一定是与当前平面上 Alice 所选的斜率相同的直线最多的那条直线平行。

accode:

#include <stdio.h>
#include <map>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 +10;
map<pair<int, int>, int> mp;
int num[maxn];

int gcd(int a, int b)   //a和b的最大公约数
{
    if(b == 0)
        return a;
    else
        gcd(b, a % b);
}

int main()
{
    int T, n, x1, y1, x2, y2;
    scanf("%d", &T);
    while(T--)
    {
        mp.clear();
        memset(num, 0, sizeof(num));
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d%d%d", &x1, &y1, & x2, &y2);
            x1 -= x2;
            y1 -= y2;
            int k = gcd(x1, y1);
            x1 /= k;
            y1 /= k;
            mp[make_pair(x1, y1)]++;
        }
        for(auto i : mp)
            for(int j = 1; j <= i.second; j++)
                num[j]++;
        for(int i = 1, j = 1; i <= n; i++)
        {
            if(!num[j]) j++; 
            num[j]--;
            printf("%d\n", i - j);
        }
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值