题意:
要求给出有n个数字的数组,有m个数组要求区间各数字不同,并且按字典排序最小;
如第三个样例:
1 2 3 1 1
1到3里的数字都是不一样的;
2到4里的数字都是不一样的。
题解:
利用贪心把所有的(l,r)按照先排 l ,再排 r 排序,用优先队列存可以用的数字,因为前面一段是已经排好,我们就可以利用前面的没被覆盖在现在的(l,r)的数字,以此类推。
代码:
#include <bits/stdc++.h>
using namespace std;
struct node{
int l, r;
}edge[100005];
int ans[100005];
int cmp(node a, node b){
if(a.l == b.l){
return a.r < b.r;
}
return a.l < b.l;
}
int main(){
int t;
scanf("%d", &t);
while(t--){
priority_queue<int, vector<int>, greater<int> > q;
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++){
q.push(i);
ans[i] = -1;
}
for(int i = 1; i <= m; i++){
scanf("%d %d", &edge[i].l, &edge[i].r);
}
sort(edge+1, edge+1+m, cmp);
int ml = 1, mr = 1;
for(int i = 1; i <= m; i++){
if(edge[i].l != edge[i+1].l || i == m){
for(int j = ml; j < edge[i].l; j++){
if(ans[j] == -1){
ans[j] = 1;
}
else{
q.push(ans[j]);
}
}
for(int j = mr; j <= edge[i].r; j++){
if(ans[j] == -1){
ans[j] = q.top();
q.pop();
}
}
ml = edge[i].l;
mr = max(mr, edge[i].r);
}
}
if(ans[1] == -1){
ans[1] = 1;
}
printf("%d", ans[1]);
for(int i = 2; i <= n; i++){
if(ans[i] == -1){
ans[i] = 1;
}
printf(" %d", ans[i]);
}
printf("\n");
}
}