2021杭电多校第三场 1004——Game on Plane

题目链接

题目大意

给你 n n n 条线段, A l i c e Alice Alice 每次从中选 k k k 条, B o b Bob Bob 每次划一条直线,定义 p e n a l t y penalty penalty B o b Bob Bob 所划直线与 A l i c e Alice Alice 所选直线相交的直线数, A l i c e Alice Alice 想最大化 p e n a l t y penalty penalty B o b Bob Bob 想最小化 p e n a l t y penalty penalty,对于每一个 1 − n 1-n 1n k k k,你都需要回答 p e n a l t y penalty penalty 的值

解题思路

显然 A l i c e Alice Alice 每次选不平行的直线是最优的,然后选最多平行数量为 2 、 3 、 4 ⋯ 2、3、4 \cdots 234 这样即可。
首先统计平行的直线有多少条,然后计算有多少种组平行数为 2 、 3 、 4 ⋯ 2、3、4 \cdots 234 的直线,用一个桶来记录,最后将这个桶求一个后缀和,然后正向输出就行。

Code

#include <bits/stdc++.h>
#define ll long long
#define qc ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define fi first
#define se second
using namespace std;
const int MAXN = 2e5 + 7;
ll v[MAXN], pre[MAXN];
int n;
map<pair<ll, ll>, int> mp;
ll gcd(ll a, ll b){
    return b ? gcd(b, a%b) : a;
}
void solve(){
    mp.clear();
    scanf("%d",&n);
    for(int i = 1; i <= n; i++){
        ll x1, y1, x2, y2;
        scanf("%lld%lld%lld%lld",&x1, &y1, &x2, &y2);
		ll xx = x1 - x2, yy = y1 - y2;
        if(xx == 0){
            mp[{0,1}]++;
        }
        else if(yy == 0){
            mp[{1,0}]++;
        }
        else{
			if(xx < 0){
				xx = -xx, yy = -yy;
			}
            ll g = gcd(xx, abs(yy));
            mp[{xx/g, yy/g}]++;
        }
    }
    for(int i = 1; i <= n; i++)
        v[i] = pre[i] = 0;
    int maxx = -1;
    for(auto it : mp){
        v[it.se]++;
    }
	pre[n+1] = 0;
    for(int i = n; i >= 1; i--)
           pre[i] = pre[i+1] + v[i];
    int cnt = 1;

    for(int i = 1; i <= n; i++){
		if(!pre[cnt]) cnt++;
		pre[cnt]--;
		printf("%d\n",i-cnt);
    }
}

int main()
{
    #ifdef ONLINE_JUDGE
    #else
       freopen("in.txt", "r", stdin);
       freopen("out.txt", "w", stdout);
    #endif

    int T;
    scanf("%d",&T);
    while(T--){

        solve();
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值