atcoder NIKKEI Programming Contest 2019-2 C Swaps

本文深入解析AtCoder竞赛中一道名为nikkei2019_2_qual_c的题目,分享作者从初见困惑到最终理解题解的心路历程。文章通过分析排序后的A、B数组特性,探讨了N-2次交换的可行性,以及如何通过节省交换次数来解决问题。此外,还讨论了如何判断交换形成的环数,并给出了一种优化方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://atcoder.jp/contests/nikkei2019-2-qual/tasks/nikkei2019_2_qual_c

比赛的时候D做出来了,然而C不知道怎么做 = =,用线段树去暴力找也WA了。

赛后看了几个人的代码,完全看不懂,像是for循环就写完了,应该是思维题,每天想一想,过了3天还是不会做

然后看了roundgod在评论区写的题解,看了半天看不懂,过了1天再配合代码看,终于领悟了,所以事实证明题目想不出要过段时间再想想,题解看不懂也可以过段时间再想想。

首先,把A,B排个序,如果排完序后的某个ai>bi,那么很显然是不行的。

然后,我们可以观察出N-2次交换,而对于1个序列,n-1次交换就一定能让他顺序完全正确,因为最差情况下最后一次交换也会使最后的两个位置同时正确,所以可以节约1次,也就是n-1次交换

所以如果拍完序后的某个aa[i+1]<=b[i] ,说明a[i]和a[i+1]之间的位置是无所谓的,那么这样也能节约一次交换,这种情况也是可行的,这里我思考花的时间最久,其实可以证明,我们把a[1]...a[i-1] a[i+2]...a[n]单独拿出来排,只要N-2次他们就归位了,剩下的a[i]和a[i+1]就不用排了,他们肯定在对应位置上或者交换位置。

最后。还要判断这些交换有几个环,由于不符合上述情况,即aa[i]<=bb[i] && aa[i+1]>bb[i],这样就说明a,b都是完全递增的,不存在数字相同的情况,所以可以离散化后把a[i]需要换到b[i]哪个位置求出来,然后如果这些交换形成了一个完整的环,那么就必须要n-1次交换,否则就会更少,环的数量为cnt,那么就只需要n-cnt次交换就行了,这题其实还可以加强。。。。

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

const int maxl=1e5+10;

int n,ans;
int a[maxl],b[maxl],aa[maxl],bb[maxl],nxt[maxl];
map <int,int> mpa,mpb;
bool vis[maxl];

inline void prework()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]),aa[i]=a[i];
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]),bb[i]=b[i];
}

inline void mainwork()
{
	ans=0;
	sort(aa+1,aa+1+n);
	sort(bb+1,bb+1+n);
	for(int i=1;i<=n;i++)
	if(aa[i]>bb[i])
		return;
	for(int i=2;i<=n;i++)
	if(aa[i]<=bb[i-1])
	{
		ans=1;
		return;
	}
	for(int i=1;i<=n;i++)
		mpa[aa[i]]=i,mpb[bb[i]]=i;
	for(int i=1;i<=n;i++)
		nxt[mpa[a[i]]]=mpb[b[i]];
	int cnt=0;
	for(int i=1;i<=n;i++)
	if(!vis[i])
	{
		int u=i;cnt++;
		while(!vis[u])
		{
			vis[u]=u;
			u=nxt[u];
		}
	}
	if(cnt>1)
		ans=1;
}

inline void print()
{
	if(ans)
		puts("Yes");
	else
		puts("No");
}

int main()
{
	prework();
	mainwork();
	print();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值