CF814B An express train to reveries

思维好题。

保证一定有解大大降低了代码难度。

显然最多有两个位置不同不然根据鸽巢原理一定存在一个序列不同位置超过一个。

然后大力分类讨论:

  • 仅有一个位置不同。此时其余位置就是排列中对应位置。否则一定存在一个序列不合法(要不一个序列超过一个要不一个序列没有)。然后将没有用过的那个数丢到这个位置即可。
  • 有两个位置不同。此时其余位置也是排列中对应位置,分析过程类似。构造方案就枚举某个序列中相同的位置,也就两种情况。

时间复杂度 (O(n))

code:

#include<bits/stdc++.h>
using namespace std;
#define N 1005
#define For(i,x,y)for(i=x;i<=(y);i++)
int vis[N];
int a[N],b[N],c[N];
int main()
{
	int n,i,x,y;
	x=y=0;
	cin>>n;
	For(i,1,n)cin>>a[i];
	For(i,1,n)
	{
		cin>>b[i];
		if(a[i]!=b[i])if(x)y=i;
		else x=i;
	}
	For(i,1,n)
	if(i!=x&&i!=y)c[i]=a[i],vis[a[i]]=1;
	if(!y)
	For(i,1,n)
	if(!vis[i])
	{
		c[x]=i;
		break;
	}
	else;else
	{
		if(!vis[a[x]]&&!vis[b[y]])c[x]=a[x],c[y]=b[y];
		else c[y]=a[y],c[x]=b[x];
	}
	For(i,1,n)cout<<c[i]<<' ';
	return 0;
}
原文地址:https://www.cnblogs.com/May-2nd/p/14366375.html