【自定义】抢妹子大作战

题目链接https://www.luogu.org/problemnew/show/U25598

这个题是我昨天在补HDU5361时根据它的优化方法想出来的一道题。我写的标解是并查集。

题意

  有n个椅子n个人,每个人都有个目标椅子,但是如果目标椅子已经被人抢了,就继续往后找。n<=10^7

  输出最后每把椅子上做的是谁。

分析

  开一个并查集,pos=find(i)代表第i把椅子右边最近的空椅子。初始时所有的椅子都是空的所以p[i]=i,最近的时它本身。

  当第i把椅子被选了以后,则更新p[find(i)]=find(i+1)。

  代码如下

  

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 const int maxn=10000000+10;
 8 int a[maxn],v[maxn],p[maxn];
 9 int T,n;
10 int find(int x){
11     return p[x]==x?x:p[x]=find(p[x]);
12 }
13 int main(){
14    // freopen("out.txt","r",stdin);
15    // freopen("out2.txt","w",stdout);
16     scanf("%d",&T);
17     for(int t=1;t<=T;t++){
18         scanf("%d",&n);
19         memset(v,0,sizeof(v));
20         for(int i=0;i<=n+2;i++)p[i]=i;
21         for(int i=0;i<=n;i++){
22             scanf("%d",&a[i]);
23         }
24         bool ok=1;
25 
26         for(int i=0;i<=n;i++){
27             int pos=find(a[i]);
28            // cout<<i<<" "<<pos<<endl;
29             if(pos>n){
30                 ok=0;
31                 break;
32             }
33             v[pos]=i;
34             p[pos]=find(pos+1);
35         }
36         if(!ok){
37             printf("-1");
38         }
39         else{
40             for(int i=0;i<=n;i++)
41                 printf("%d ",v[i]);
42         }
43         printf("
");
44     }
45 return 0;
46 }
View Code
原文地址:https://www.cnblogs.com/LQLlulu/p/9033844.html