洛谷 CF1110E Magic Stones【差分】【思维】


题意:

有两个数组,分别为操作数组 c c c与目标数组 t t t
一次操作选择 1 < i < n 1<i<n 1<i<n,使 c i c_i ci变为 c i ′ = c i + 1 + c i − 1 − c i c_i'=c_{i+1}+c_{i-1}-c_i ci=ci+1+ci1ci
是否能做若干次操作,使每个 c i c_i ci t i t_i ti相等


分析:

我们设 s i s_i si为差分数组,有 s i = c i − c i − 1 s_i=c_{i}-c_{i-1} si=cici1
考虑当我们改变 c i c_i ci时, s i & s i + 1 s_i\& s_{i+1} si&si+1的变化
s i = c i − 1 + c i + 1 − c i − c i − 1 = c i + 1 − c i s_i=c_{i-1}+c_{i+1}-c_i-c_{i-1}=c_{i+1}-c_i si=ci1+ci+1cici1=ci+1ci
s i + 1 = c i + 1 − c i + 1 − c i − 1 + c i = c i − c i − 1 s_{i+1}=c_{i+1}-c_{i+1}-c_{i-1}+c_i=c_i-c_{i-1} si+1=ci+1ci+1ci1+ci=cici1
也就是相当于每次操作本质上就是交换了差分数组中相邻的位置,那么可行性就很好判定了


代码:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<cmath>
#define LL long long 
using namespace std;
inline LL read() {
    
    
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){
    
    if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){
    
    d=d*10+s-'0';s=getchar();}
    return d*f;
}
int a[100005],b[100005],c1[100005],c2[100005];
int main()
{
    
    
	int n=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) b[i]=read();
	if(a[1]!=b[1]||a[n]!=b[n]) return !printf("No");
	for(int i=1;i<n;i++) c1[i]=a[i+1]-a[i],c2[i]=b[i+1]-b[i];
	sort(c1+1,c1+n);sort(c2+1,c2+n);
	for(int i=1;i<n;i++) if(c1[i]!=c2[i]) return !printf("No");
	printf("Yes");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/108782385