题目大意:每个人给另一个人礼物,要求每个人都分配到礼物,并且礼物来源不能来自自己(就是要求错开)
思路:首先把没有送过礼的人的编号存起来,然后设置一个下标sta,用于记录上一个没有送过礼的人的下标,后面只需要当礼物分配时发现了自己送自己的情况,只需要和前面的互换礼物就可以了(因为一个人只和一个礼物冲突,礼物也是如此,所以换过去和换过来的不会出现自己送自己的情况),需要再对第一个自己送自己,第二个合法的情况特判一下
丑陋的code:93ms
#include<bits/stdc++.h>
using namespace std;
const int maxx = 2e5+10;
int a[maxx],b[maxx],c[maxx];
int main ()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++){
scanf("%d",&a[i]);
b[a[i]]=1;
}
int p = 0;
for(int i=1; i<=n; i++) {
if(b[i]==0)
c[p++] = i;
}
int idx = 0,sta=0,f=0;
for(int i=1; i<=n; i++){
if(a[i]==0 && c[idx] == i) {
if(sta==0){
f=1;
sta = i;
a[i] = i;
}else{
a[i] = a[sta];
a[sta] = c[idx];
sta = i;
}
idx++;
}
else if(a[i]==0 && c[idx]!=i){
if(idx==1 && f==1){
a[i] = a[sta];
a[sta] = c[idx];
sta = i;
idx++;
}else{
a[i] = c[idx];
sta = i;
idx++;
}
}
}
for(int i=1; i<=n; i++){
if(i==1)
printf("%d",a[i]);
else
printf(" %d",a[i]);
}
return 0;
}