HDU6301 Distinct Values

2018 Multi-University Training Contest 1 1004

18.7.23的多校第四题

因为sort从0开始没有从1开始还wa了5发

说下大概思路好了

开一个初始为1大小100005的数组和一个从1到n的优先队列

输入所有要求 按先左端点后右端点从小到大排序

然后遍历 把满足循环条件的第一组要求的左右端点标记下来 分别记为left和right 并把优先队列的数赋值后推出

如果要求的右端点>right 就先把left到左端点之间的数先push进优先队列

然后继续用优先数列的数给right后面的数赋值

不会码字 大家看代码吧

#include <bits/stdc++.h>

using namespace std;

int a[100005];
struct node {
    int left,right;
} b[100005];

bool cmp(node b1, node b2) {
    if(b1.left != b2.left)
        return b1.left < b2.left;
    return b1.right < b2.right;
}

int main() {
    int t,n,m;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);

        //greater<int>表示数值小的优先级越大(小项堆)
        //priority_queue默认为大顶堆
        priority_queue< int, vector<int>, greater<int> > q;
        for(int i = 1; i <= n; i++) q.push(i);

        fill(a,a+100005,1);

        for(int i = 1; i <= m; i++) {
            scanf("%d %d",&b[i].left,&b[i].right);
        }
        sort(b + 1, b + 1 + m, cmp);

        int left, right;
        int flag = 1;
        for(int i = 1; i <= m; i++) {
            if(b[i].left != b[i+1].left || i == m) {
                if(flag) {
                    left = b[i].left;
                    right = b[i].right;
                    for(int j = b[i].left; j <= b[i].right; j++) {
                        a[j] = q.top();
                        q.pop();
                    }
                    flag = 0;
                }
                for(int j = left; j < b[i].left; j++) {
                    q.push(a[j]);
                }
                for(int j = right+1; j <= b[i].right; j++) {
                    a[j] = q.top();
                    q.pop();
                }
                left = b[i].left;
                right = max(b[i].right,right);
            }
        }

        for(int i = 1; i <= n; i++) {
            if(i!=1) printf(" ");
            printf("%d",a[i]);
        }
        printf("\n");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41989228/article/details/81185142