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 }