• hdu 6301 Distinct Values(贪心)题解


    题意:长为n的串,给你m个区间,这些区间内元素不重复,问这样的串字典序最小为?

    思路:用set保存当前能插入的元素,这样就能直接插入最小元素了。对操作按l排序,因为排过的不用排,所以两个指针L,R是一直右移的。L右移肯定是增加set中元素,R右移有两种可能:一是L在R右边,R只是负责赶路赶到操作区间;二是L在R左边,那么R右移是在扩大区间,并且对数组中元素进行插入。

    代码:

    #include<cstdio>
    #include<vector>
    #include<set>
    #include<queue>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #define ll long long
    const int maxn = 100000+5;
    const int maxm = 100000+5;
    const int MOD = 1e7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    struct node{
        int l,r;
    }q[maxn];
    bool cmp(node a,node b){
        return a.l == b.l? a.r < b.r : a.l < b.l;
    }
    int ans[maxn];
    int main(){
        int T;
        int n,m;
        scanf("%d",&T);
        while(T--){
            memset(ans,0,sizeof(ans));
            scanf("%d%d",&n,&m);
            set<int> s;
            for(int i = 1;i <= n;i++){
                s.insert(i);
            }
            for(int i = 0;i < m;i++)
                scanf("%d%d",&q[i].l,&q[i].r);
            sort(q,q+m,cmp);
            for(int i = q[0].l;i <= q[0].r;i++){
                ans[i] = *s.begin();
                s.erase(ans[i]);
            }
            int L = q[0].l,R = q[0].r;
            for(int i = 1;i < m;i++){
                while(L < q[i].l){
                    if(ans[L] != 0) s.insert(ans[L]);
                    L++;
                }
                while(R < q[i].r){
                    if(L > R){
                        if(ans[R] != 0) s.insert(ans[R]);
                        R++;
                    }
                    else{
                        if(L == R){
                            if(ans[R] == 0){
                                ans[R] = *s.begin();
                                s.erase(ans[R]);
                            }
                            else s.erase(ans[R]);
                            R++;
                            if(ans[R] == 0){
                                ans[R] = *s.begin();
                                s.erase(ans[R]);
                            }
                            else s.erase(ans[R]);
                        }
                        else{
                            R++;
                            if(ans[R] == 0){
                                ans[R] = *s.begin();
                                s.erase(ans[R]);
                            }
                        }
    
                    }
                }
            }
            for(int i = 1;i <= n;i++){
                if(i != 1) printf(" ");
                if(ans[i] == 0) printf("1");
                else printf("%d",ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    第二次作业
    java第一次上机练习
    java第一次作业
    第四周上机作业
    第三周作业
    第一次上机作业
    第一次作业
    3.19第三周上机作业
    第一周课下作业
    2020.3.23 java第三次作业
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408749.html
Copyright © 2020-2023  润新知