题目链接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 }