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 N, Ai≤Bi 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;
}