HDU 6301 Distinct Values (set)

【題目鏈接】
http://acm.hdu.edu.cn/showproblem.php?pid=6301

題目意思

讓你尋找一個長度爲n的最小字典序數組,數組滿足m個區間任意兩數值不同。

解題思路

用數組pre[i]記錄以i爲右區間的最左區間,也就是i能覆蓋的最大區間。然後用set來記錄能使用的數值。從左往右填值。在一個區間的不斷彈出數值,如果在區間左邊也就是小於pre[i],把之前彈出的數值補回。
注意:如果區間[1,4]不同的話那麼2和3的pre也要更新成1.(這樣可以去除完全被覆蓋的小區間)。實現這一操作只要倒在找min(pre[i],pre[i+1]).

代碼部分


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <map>
#include <math.h>
#include <set>
using namespace std;
#define LL long long
#define inf 0x3f3f3f3
const int mod = 1e9+7;
const int N = 1e5+7;
int pre[N];  ///以i爲終點覆蓋的最大區間 
int a[N];  ///存放答案 
set<int>q;
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d %d",&n,&m);
        q.clear();
        for (int i = 1; i <= n; i++)
        {
            pre[i] = i;
            q.insert(i);
        }   
        for(int i = 0; i < m; i++)
        {
            int l,r;
            scanf("%d %d",&l,&r);
            pre[r] = min(pre[r],l);
        } 
        for (int i = n-1; i > 0; i--)
            pre[i] = min(pre[i],pre[i+1]); ///如輸入1,4.那麼2,3的下標也跟新成1.去掉完全被覆蓋的小區間 
        int pl = 1;   ///標記不重複的起點 
        for (int i = 1; i <= n; i++)
        {
            while (pl < pre[i])  ///區間的最左比起點大,把之前使用的數值補回 
            {
                q.insert(a[pl]);
                pl++;
            }
            a[i] = *q.begin();
            q.erase(a[i]);
        }
        for (int i = 1; i <= n; i++)
            printf("%d%c",a[i]," \n"[i==n]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章