Friends and Gifts(思维乱搞)

There are nn friends who want to give gifts for the New Year to each other. Each friend should give exactly one gift and receive exactly one gift. The friend cannot give the gift to himself.

For each friend the value fifi is known: it is either fi=0fi=0 if the ii-th friend doesn’t know whom he wants to give the gift to or 1≤fi≤n1≤fi≤n if the ii-th friend wants to give the gift to the friend fifi.

You want to fill in the unknown values (fi=0fi=0) in such a way that each friend gives exactly one gift and receives exactly one gift and there is no friend who gives the gift to himself. It is guaranteed that the initial information isn’t contradictory.

If there are several answers, you can print any.

Input
The first line of the input contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the number of friends.

The second line of the input contains nn integers f1,f2,…,fnf1,f2,…,fn (0≤fi≤n0≤fi≤n, fi≠ifi≠i, all fi≠0fi≠0 are distinct), where fifi is the either fi=0fi=0 if the ii-th friend doesn’t know whom he wants to give the gift to or 1≤fi≤n1≤fi≤n if the ii-th friend wants to give the gift to the friend fifi. It is also guaranteed that there is at least two values fi=0fi=0.

Output
Print nn integers nf1,nf2,…,nfnnf1,nf2,…,nfn, where nfinfi should be equal to fifi if fi≠0fi≠0 or the number of friend whom the ii-th friend wants to give the gift to. All values nfinfi should be distinct, nfinfi cannot be equal to ii. Each friend gives exactly one gift and receives exactly one gift and there is no friend who gives the gift to himself.

If there are several answers, you can print any.

Examples
Input
5
5 0 0 2 4
Output
5 3 1 2 4
Input
7
7 0 0 1 4 0 6
Output
7 3 2 1 4 5 6
Input
7
7 4 0 3 0 5 1
Output
7 4 2 3 6 5 1
Input
5
2 1 0 0 0
Output
2 1 4 5 3
题意:n个人互相给另一个人礼物,一个人只能收到一份礼物,每个人不能给自己礼物,已经有几个人知道给谁了,但是还有人不知道。构造出这样的序列来符合题意。
思路:一共有四种人;
①即收到礼物又送出礼物
②没有收到礼物也没有送出礼物
③收到礼物但是没有送出礼物
④送出礼物但是没有收到礼物
对于②类型人,我们要优先安排,否则有可能自己给自己送重了。剩下的人就随意安排了。
具体看代码:

#include<bits/stdc++.h>
using namespace std;

const int maxx=2e5+100;
int a[maxx];
int vis[maxx];
int n;

int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		memset(vis,0,sizeof(vis));
		vector<int> t1,t2,t3;
		for(int i=1;i<=n;i++) 
		{
			scanf("%d",&a[i]);
			if(a[i]) 
			{
				vis[i]+=1;
				vis[a[i]]+=2;
			}
		}
		for(int i=1;i<=n;i++)
		{
			if(vis[i]==0) t1.push_back(i);//既没有送出礼物,也没有收到 
			else if(vis[i]==1) t2.push_back(i);//送出礼物,但是没有收到礼物 
			else if(vis[i]==2) t3.push_back(i);//收到礼物,但是没有送出礼物
		}
		if(t1.size()&1)//②类型的人有奇数个,那就先安排一个
		{
			if(t2.size()) 
			{
				a[t1[0]]=t2[0];
				t2.erase(t2.begin());
				t2.push_back(t1[0]);
				t1.erase(t1.begin());
			}
			else if(t3.size())
			{
				a[t3[0]]=t1[0];
				t3.erase(t3.begin());
				t3.push_back(t1[0]);
				t1.erase(t1.begin());
			}
			else//只有②类型的人,那样就好弄了。
			{
				for(int i=1;i<t1.size();i++)
				{
					a[t1[i]]=t1[i-1];
				}
				a[t1[0]]=t1[t1.size()-1];
				for(int i=1;i<=n;i++) cout<<a[i]<<" ";
				cout<<endl;
				return 0;
			}
		}
		int l=0,r=t1.size()-1;
		while(l<r)//既没有送出礼物,也没有收到礼物的互相匹配,是偶数了,就一定可以互相匹配了
		{
			a[t1[l]]=t1[r];
			a[t1[r]]=t1[l];
			l++,r--;
		}
		for(int i=0;i<t2.size();i++) a[t3[i]]=t2[i];//3和4类型的互相匹配
		for(int i=1;i<=n;i++) cout<<a[i]<<" ";
		cout<<endl;
	}
	return 0;
}

容易想到用匈牙利算法去做,但是2e5的时间复杂度容易超时。
努力加油a啊,(o)/~

发布了414 篇原创文章 · 获赞 23 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/104080970
今日推荐