HDU 6301.Distinct Values-贪心、构造字典序最小的数列 (2018 Multi-University Training Contest 1 1004)

HDU6301.Distinct Values

这个题就是给你区间要求区间内的数都不相同,然后要求是字典序最小,直接贪心走一遍,但是自己写的时候,思路没有错,初始化写挫了。。。

将区间按左端点小的排序,如果相同就按右端点大的排序,因为右端点大的肯定满足右端点小的。然后直接标记数组记录当前区间已有的数,然后将没有的数字填到里面。注意初始化就可以了。

代码:

 1 //1004-6301-字典序最小的序列,贪心策略,标记当前段出现过的
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<cstdlib>
 8 #include<cassert>
 9 using namespace std;
10 typedef long long ll;
11 const int maxn=1e5+10;
12 
13 struct node{
14     int l,r;
15      bool operator< (const node &a) const {
16          if(l==a.l) return r>a.r;
17          else return l<a.l;
18      }
19 
20 }a[maxn];
21 
22 int cnt[maxn],ans[maxn];
23 int main()
24 {
25     int t;
26     scanf("%d",&t);
27     while(t--){
28         int n,m;scanf("%d%d",&n,&m);
29         memset(cnt,0,sizeof(cnt));
30         memset(ans,0,sizeof(ans));
31         for(int i=0;i<m;i++)
32             scanf("%d%d",&a[i].l,&a[i].r);
33         sort(a,a+m);
34         for(int i=a[0].l;i<=a[0].r;i++)
35             ans[i]=i-a[0].l+1;
36         int num,L=a[0].l,R=a[0].r;
37         for(int i=1;i<m;i++){
38             if(a[i].r<=R) continue;
39             num=1;
40             if(a[i].l<=R){
41                 for(int j=a[i].l;j<=R;j++)
42                     cnt[ans[j]]=i;
43                 for(int j=R+1;j<=a[i].r;j++){
44                     while(cnt[num]==i)++num;
45                     ans[j]=num++;
46                 }
47                 L=a[i].l,R=a[i].r;
48             }
49             else{
50                 for(int j=a[i].l;j<=a[i].r;j++)
51                     ans[j]=num++;
52                 L=a[i].l,R=a[i].r;
53             }
54         }
55         for(int i=1;i<n;i++){
56             if(ans[i])printf("%d ",ans[i]);
57             else printf("1 ");
58         }
59         if(ans[n])printf("%d
",ans[n]);
60         else printf("1
");
61     }
62     return 0;
63 }
原文地址:https://www.cnblogs.com/ZERO-/p/9385544.html