CF1365F Solution

题目链接

题解

可以发现,如果\(a\)数组存在对称元素(\(a_i,a_{n-i+1}\))在\(b\)数组中位置并非对称,则一定无法变换成功,因为无论如何操作对称元素均不会变(如果有多个相等的数则尽量使其合法)。

而如果满足位置对称,则一定存在可行变换方案:\(\{a_1,a_2,...,a_j,...,a_i,...,a_{n/2},...,a_{n-i+1},...,a_{n-j+1},...,a_n\}\),设\([a_{i+1},a_{n-i}]\)已经完成变换,现在需要将\(a_j,a_{n-j+1}\)移动至\(a_i,a_{n-i+1}\)处。先进行一次\(k=j\)的变换,使\(a_j,a_{n-j+1}\)移动至数组的右、左端点;再进行\(k=i\)的变换即可完成移动,且不对\([a_{i+1},a_{n-i}]\)产生影响。

因此只需要判断对称元素是否相同即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=510;
struct node {int x,y;} pa[N],pb[N];//pa/b:a/b数组中的对称元素对
int a[N],b[N];
bool cmp(node x,node y) {return x.x<y.x || (x.x==y.x && x.y<y.y);}  
int main()
{
	int t,n;
	scanf("%d",&t);
	while(t--) 
	{
		bool flag=1;//flag=0/1:NO/YES
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		for(int i=1;i<=n;i++) scanf("%d",&b[i]);//若n为奇数,中间项也需相等
		if(n%2 && a[n/2+1]!=b[n/2+1]) {printf("NO\n"); continue;}
		for(int i=1;i<=(n+1)/2;i++) 
		{
			pa[i].x=a[n-i+1],pa[i].y=a[i];
			if(pa[i].x>pa[i].y) swap(pa[i].x,pa[i].y);//为下排序最准备
			pb[i].x=b[n-i+1],pb[i].y=b[i];
			if(pb[i].x>pb[i].y) swap(pb[i].x,pb[i].y);
		}
		sort(pa+1,pa+(n+1)/2+1,cmp),sort(pb+1,pb+(n+1)/2+1,cmp);//使x,y相等的元素对聚集在一起
		for(int i=1;i<=(n+1)/2;i++)
			if(pa[i].x!=pb[i].x || pa[i].y!=pb[i].y) {flag=0; break;}
		if(!flag) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/violetholmes/p/14449699.html