hdu 6301 Distinct Values(贪心)

题目

题意:给你一个区间的长度n和m个限制条件的区间,m个区间中的数字不能重复,问此区间字典树最小的方法是什么。

这题在多校的时候,本来以为能水过去,想想当时还是太天真了,这题没仔细考虑的话,以我原来的做法有好多bug,根本改不完,后来看了一下大佬的代码。。还是疯狂wa,。。看这题看了好久啊。。越来越没效率了。。。

思路:首先我们要知道区间不重复出现数字,最简单的方法并且最好用的方法就是用set函数进行存储可以用的数字,每次使用数字,从set里提取出来再删掉就行了。其它的看注释吧。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;

const int maxn = 1e5+10;
int ends[maxn],col[maxn];    //ends[i],记录以i为起点的的最大结尾为多少。 col,记录每个位置的数字。
int main(){
    int t, n, m, i;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        memset(ends, -1, sizeof(ends));
        for(i = 1; i <= n; i++)
            ends[i] = i;    //初始化,把每个点都看成以自己开始自己结束的一个区间。这里很重要。
        for(i = 1; i <= m; i++){ 
            int l, r;
            scanf("%d%d",&l,&r);
            ends[l] = max(ends[l],r);    //判断此前是否出现更大的区间范围
        }
        set<int> s;                     //记录可以使用的数字
        for(i = 1; i <= n; i++)         //把1~n都存入set
            s.insert(i);
        int l = 1, r = 0;
        for(i = 1; i <= n; i++){       //判断每个区间,i就是每个区间的起始点
            if(r >= ends[i])           //ends[i]的区间已经被更新过,跳过 
                continue;
            while(l < i)               //起始点i之前使用过的数字都变为可行数字,加入set
                s.insert(col[l++]);
            while(r < ends[i]){        //更新当前区间的col
                col[++r] = *s.begin();
                s.erase(col[r]);
            }
        }
        for(i = 1; i <= n; i++){
            if(i-1)
                putchar(' ');
            printf("%d",col[i]);
        }
        puts("");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值