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; }