CF-div3-611-C. Friends and Gifts|思维
思路
开两个数组
一个一个匹配,如果值相同,就与下一个交换;
注意边界:当i==n时,与第1个元素交换,此时能够保证正确性:因为元素不重复,第n个元素值相同的话,说明第一个元素与第n个的就不同了,交换就完事了。
小结
第一次写错因:没想边界,
好吧是想到了边界但是没往深处想,还以为边界不影响,下次要改,多想想!
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+100;
int n;
int lenb = 0,lenc = 0;
int a[maxn],b[maxn],c[maxn*2],ans[maxn];
int vis[maxn];
bool cmp(int u,int v){
return u>v;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) {
cin>>a[i];
vis[a[i]] = 1;
if(a[i] == 0) b[++lenb] = i;
else ans[i] = a[i];
}
for(int i=1;i<=n;i++) if(vis[i] == 0) c[++lenc] = i;
// sort(b+1,b+lenb+1); //排不排序都无所谓
// sort(c+1,c+lenc+1,cmp);
for(int i=1;i<=lenb;i++){
if(b[i] == c[i]) {
if(i == lenb) //因为如果是最后一个 有可能还是相同 这样就出错
swap(c[i],c[1]); //所以可以与第一个交换 原因是c[末尾] = b[末尾] 那么c第一个元素肯定不和b第一个相同(前面相同的都交换匹配好了),也不和b第末尾个相同
else
swap(c[i],c[i+1]);
}
}
for(int i=1;i<=n;i++) ans[i] = a[i];
for(int i=1;i<=lenb;i++) ans[b[i]] = c[i];
for(int i=1;i<n;i++) cout<<ans[i]<<" ";
cout<<ans[n];
return 0;
}
/*
3
0 0 1
6
0 3 2 5 4 0
*/