AtCoder5634 Swaps (置换群)

Swaps


Time limit : 2sec / Memory limit : 1024MB

Score : 600 points

Problem Statement

Given are two integer sequences of N elements each: A1,…,AN and B1,…,BN. Determine if it is possible to do the following operation at most N−2 times (possibly zero) so that, for every integer i from 1 to NAiBi holds:

  • Choose two distinct integers x and y between 1 and N (inclusive), and swap the values of Ax and Ay.

Constraints

  • 2≤N≤105
  • 1≤Ai,Bi≤109

Input

Input is given from Standard Input in the following format:

N
A1 A2 … AN
B1 B2 … BN

Output

If the objective is achievable, print Yes; if it is not, print No.


Sample Input 1

Copy

3
1 3 2
1 2 3

Sample Output 1

Copy

Yes

We should swap the values of A2 and A3.


Sample Input 2

Copy

3
1 2 3
2 2 2

Sample Output 2

Copy

No

Sample Input 3

Copy

6
3 1 2 6 3 4
2 2 8 3 4 3

Sample Output 3

Copy

Yes

链接:https://vjudge.net/problem/AtCoder-5634

题意:每个数组n个数,将数组A[]中数两两交换,问是否能在n-2次交换下,满足A[i]<=B[i]

题解:

置换群(解决问题:将当前顺序的状态数[4,1,2,3]交换成为[1,2,3,4],至少需要多少次交换?)3次!

计算方法:当前状态[4,1,2,3]转为目的状态,可看为一个圈【4->3->2->1】

(第一个数40要去第四个位置,第四个数要去第三个位置,第三个数要去第二个位置,...)刚好形成一个环

比如:[4,3,2,1]->[1,2,3,4]就是两个圈;[4,2,3,1]->[1,2,3,4]是三个圈。

然后..每个圈内需要n-1次最少交换形成最终状态。

比如:[4,1,2,3]需要4-1次交换;[4,3,2,1]需要(2-1)+(2-1)次交换;[4,2,3,1]需要(2-1)+(1-1)+(1-1)次交换

回到这道题~

本题说在n-2次交换内完成状态,一个圈时候是n-1,所以至少两个圈吧

推导:两个圈分别是a,b人,a+b=n,n个人完成交换至少需要(a-1)+(b-1)=a+b-2=n-2

但是一个圈时,某种样例下也是YES

/*4  , 1 , 2 , 3

  10,20,30,40 */ 该样例A数组并不需要交换,但是A确实一个圈。(特判一下)

该题步骤:

1.先sort(A),sort(B)

2.先检查是否无论怎么交换,都不会满足A[i]<=B[i]    NO

3.有可能是一个圈,但是有些数没必要交换  A[i+1]<=B[i]   YES

4.一个圈是NO,多个圈是YES

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stdio.h>
using namespace std;
int n;
struct node 
{
	int v;
	int id;
}a[100005],b[100005];
int book[100005];
int to[100005];
bool cmp(node x,node y)
{
	return x.v<y.v;
}
void solve()
{
	sort(a+1,a+n+1,cmp);
	sort(b+1,b+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		if(a[i].v>b[i].v)
		{
			cout<<"No"<<endl;
			return;
		}
	}
	for(int i=1;i<n;i++)
	{
		if(a[i+1].v<=b[i].v)
		{
			cout<<"Yes"<<endl;
			return;
		}
	}
	for(int i=1;i<=n;i++)
	{
		to[a[i].id]=b[i].id;
	}
	int qnum=0;
	for(int i=1;i<=n;i++)
	{
		int top=i,flag=0;
		while(book[top]==0)
		{
			flag=1;
			book[top]=1;
			top=to[top];
		}
		if(flag) qnum++;
	}
	if(qnum!=1)
	cout<<"Yes"<<endl;
	else
	{
		cout<<"No"<<endl;
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i].v),a[i].id=i;
	for(int i=1;i<=n;i++)
	scanf("%d",&b[i].v),b[i].id=i;
	solve();
	return 0;
} 
发布了39 篇原创文章 · 获赞 27 · 访问量 4114

猜你喜欢

转载自blog.csdn.net/qq_43381887/article/details/103044837