HDU 6301 Distinct Values

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6301

多校contest1

题目大意是有一个长度为N的数组,给出M个"事实",每个事实指明一段区间内数字各异,求最后字典序最小的数组。

贪心+构造,给所有"事实"按 边界(左边界优先)排序,然后扫一遍"事实",用一个队列保证用以构造的所有数字最小且区间内各异。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define fst    first
 4 #define scd second
 5 typedef pair<int ,int > pii;
 6 
 7 vector< pii >    facts;
 8 queue< int > num;
 9 bool inq[100000+5];
10 int ans[100000+5];
11 
12 int main(){
13     int Test;
14     scanf("%d",&Test);
15     while(Test--){
16         int N,M;
17         scanf("%d%d",&N,&M);
18         memset(inq,false,sizeof(inq));
19         while(!num.empty()) num.pop();
20         facts.clear();
21         for(int i=1;i<=N;++i) ans[i]=1;
22         for(int i=0;i<M;++i){
23             pii tmp;
24             scanf("%d%d",&tmp.fst,&tmp.scd);
25             if(tmp.fst!=tmp.scd) facts.push_back(tmp);
26         }
27         sort(facts.begin(),facts.end());
28         int lastr=-1,lastl=-1;
29         for(int i=0;i<facts.size();++i){
30             int l=facts[i].fst,r=facts[i].scd; 
31             if(r<=lastr) continue;
32             if(l>lastr){
33                 while(!num.empty()) {
34                     inq[num.front()]=false;
35                     num.pop();
36                 }
37                 int cnt=1;
38                 for(int i=l;i<=r;++i){
39                     int flag=0;
40                     while(!flag){
41                         if(!inq[cnt]){
42                             inq[cnt]=true;
43                             num.push(cnt);
44                             ans[i]=cnt;
45                             flag=1;
46                         }
47                         cnt++; 
48                     }
49                 }
50                 lastr=r;
51                 lastl=l;
52                 continue;
53             }
54             if(l<=lastr){
55                 for(int i=0;i<l-lastl;++i) {
56                     inq[num.front()]=false;
57                     num.pop();
58                 }
59                 int cnt=1;
60                 for(int i=lastr+1;i<=r;++i){
61                     int flag=0;
62                     while(!flag){
63                         if(!inq[cnt]){
64                             inq[cnt]=true;
65                             num.push(cnt);
66                             ans[i]=cnt;
67                             flag=1;
68                         }
69                         cnt++; 
70                     }
71                 }
72                 lastl=l;
73                 lastr=r;
74                 continue;
75             }
76         }
77         for(int i=1;i<=N;++i) printf("%d%c",ans[i],i==N?'\n':' ');
78     }
79     return 0;
80 }
View Code

猜你喜欢

转载自www.cnblogs.com/Kiritsugu/p/9362709.html