2020ICPC南京 L.Let‘s Play Curling(思维+尺取)

题意:

给定长度为n的整数数组a,和长度为m的整数数组b,
表示在一维数轴上有n个红点a[i],和m个蓝点b[i],
给定一个实数c,对于每一个i,如果对于所有的j,
都满足|c-a[i]|<|c-b[j]|,那么红队分数+1,
现在你可以自定义c的值,计算红队可能获得的最大分数.

数据范围:n,m<=5e5

解法:
发现问题可以变为:
将a数组和b数组混合,问题变为计算最大子区间的长度,
满足整个区间只有红色,(因为可以取c为区间中点),
混合起来,排个序,然后尺取一下即可.

坑点:
观察到红点和蓝点可能重叠,这样的红点可以直接丢弃,
但是蓝点不能丢弃!
code:
#include <bits/stdc++.h>
using namespace std;
const int maxm=1e6+5;
struct Node{
    int x,f;
}e[maxm];
int a[maxm];
int b[maxm];
int n,m;
bool cmp(Node a,Node b){
    return a.x<b.x;
}
signed main(){
    ios::sync_with_stdio(0);cin.tie(0);
    int T;cin>>T;
    while(T--){
        cin>>n>>m;
        map<int,int>mark;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        for(int i=1;i<=m;i++){
            cin>>b[i];
            mark[b[i]]=1;
        }
        int num=0;
        for(int i=1;i<=n;i++){
            if(!mark[a[i]]){
                e[++num]={a[i],0};
            }
        }
        for(int i=1;i<=m;i++){
            e[++num]={b[i],1};
        }
        sort(e+1,e+1+num,cmp);
        int ans=0;
        int cnt[2]={0};
        int l=1;
        for(int i=1;i<=num;i++){
            cnt[e[i].f]++;
            while(cnt[1]){
                cnt[e[l].f]--;
                l++;
            }
            ans=max(ans,i-l+1);
        }
        if(ans==0)cout<<"Impossible"<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值