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
*/ 
原文地址:https://www.cnblogs.com/fisherss/p/12345897.html