[CF div2 Educational Round 58]C.Division and Union

本文介绍了一种解决CF C题的有效策略,通过将区间按左边界排序,首先分配首个区间及其相连区间到一组,剩余区间归为另一组,以此实现区间无交集分组。若无法分组则输出-1。

题目链接:

C. Division and Union

题意描述:

给出n个闭区间,要求把n个区间分成两组,使两组没有公共点。

输入:

第一行样例数T

随后T组样例,每个样例第一行一个n,随后n行每行两个数l,r

输出:

按所给顺序输出每个区间的分组,1代表第一组,2代表第二组。多种可能分组,随意输出一种。(SPJ)

思路:

这场CF真的给做自闭了,B题少判断一种情况被人hack,卡C题后面签到题E题很晚才过,最后十分钟意识到C的思路是错的,不是找一个孤立区间,剩下的全分到一组。。然而来不及改了。。C也没做出来,只过了两题???疯狂掉分。。。

至于这道C题,赛后趴桌子上想了没几分钟就想出了正确做法:

所有区间按l大小排个序,然后把第一个区间和与第一个区间相连的区间都扔到一组里面,剩下的留在另一组。

如果另一组为空,则表示所有区间全部相连,那么就输出-1

多么简单的思路。。。为什么比赛的时候就想不出呢。。。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
static const int maxn = 100010;
static const int INF = 0x3f3f3f3f;
static const int mod = (int)1e9 + 7;
static const double eps = 1e-6;
static const double pi = acos(-1);

void redirect(){
    #ifdef LOCAL
        freopen("test.txt","r",stdin);
    #endif
}

struct node{
    int id,l,r;
    bool operator <(const node& y){
        return this->l < y.l;
    }
}p[200010]; 

int main(){
    redirect();
    int T,n;
    scanf("%d",&T);
    while(T--){
        set<int>s;
        scanf("%d",&n);
        for(int i = 1;i <= n;i++){
            p[i].id = i;
            scanf("%d %d",&p[i].l,&p[i].r);
        }
        sort(p+1,p+1+n);
        s.insert(p[1].id);
        int maxr = p[1].r;
        bool flag = false;
        for(int i = 1;i <= n;i++){
            if(p[i].l > maxr){flag = true;break;}
            s.insert(p[i].id);
            maxr = max(maxr,p[i].r);
        }
        if(flag){
            for(int i = 1;i <= n;i++){
                if(s.count(i))printf("1");
                else printf("2");
                printf("%c",i==n?'\n':' ');
            }
        }
        else puts("-1");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值