CF28B pSort

题目描述

给定一个含有n个元素的数列,第i号元素开始时数值为i,元素i可以与距离为d[i]的元素进行交换。再给定一个1-n的全排列,问初始的数列可否交换成给定的样式。

输入:第一行一个整数n,第二行n个互不相同的整数表示目标数列,第三行n个整数表示d[i];

输出:如果能交换到给定样式,输出"YES",否则输出"NO"。

1<=n<=100

输入输出样例

输入 #1

5
5 4 3 2 1
1 1 1 1 1

输出 #1

YES

输入 #2

7
4 3 5 1 2 7 6
4 6 6 1 6 6 1

输出 #2

NO

输入 #3

7
4 2 5 1 3 7 6
4 6 6 1 6 6 1

输出 #3

YES

解题思路

最近一直在做cf的题目,不得不说cf的题目实在是太有趣了233333

这题很明显是个并查集,对于i-d[i],i+d[i]的可移动的区域进行一个合并就ok了

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=100+5;
int f[N],d[N],fa[N];
int find(int x) {
    if(x==fa[x])return x;
    return fa[x]=find(fa[x]);
}
void merge(int x,int y) {
    x=find(x),y=find(y);
    if(x==y)return;
    fa[y]=x;
}
int main() {
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)cin>>f[i];
    for(int i=1; i<=n; i++)cin>>d[i];
    for(int i=1; i<=n; i++)fa[i]=i;
    for(int i=1; i<=n; i++) {
        if(i-d[i]>=1)merge(i,i-d[i]);
        if(i+d[i]<=n)merge(i,i+d[i]);
    }
    for(int i=1; i<=n; i++) {
        if(find(i)!=find(f[i])) {
            cout<<"NO"<<endl;
            return 0;
        }
    }
    cout<<"YES"<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/Larry-Zero/p/11770414.html