CF28B pSort

发布时间 2023-06-07 21:21:14作者: jiangchenyangsong

2021-03-16

大致题意

给你一串数字,然后告诉你每一个格子能与哪些格子中的数字交换,问你最后能不能得到给你的一组排列。

思路

对于位置i,可以与位置(i+d[i])和(i-d[i])位置的数交换

则可以考虑把位置i可以交换的位置放入一个集合里,就想到用并查集来解决。

如样例2,合成的集合有{1,5,4,3} {2} {7,6},则1,5,4,3位置上的数可以相互交换。

所以只要判断初始数与最终的值是否在同一集合即可。

详见代码

#include<bits/stdc++.h>
using namespace std;
int n,a[105],d[105],father[105];
int find(int x){   //找father 
	if(father[x]!=x) father[x]=find(father[x]);
	return father[x];
}
int merge(int x,int y){   //合并为同一集合 
	int x1=find(x);
	int y1=find(y);
	father[y1]=x1;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		father[i]=i;     //初始化 
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&d[i]);   //考虑是否越界 
		if(i-d[i]>0) merge(i,i-d[i]);    //把第i个元素能到的格子合并为同一集合 
		if(i+d[i]<=n) merge(i,i+d[i]);
	}
	for(int i=1;i<=n;i++){
		if(find(i)!=find(a[i])){   //判断是否在同一集合里 
			printf("NO\n");   //只要有一个点不行就输出NO
			return 0;
		}
	}
	printf("YES\n");
	return 0;
}

完结撒花~~~~