【洛谷CF1110E】Magic Stones

【洛谷CF1110E】Magic Stones


题目描述

多个询问,
每个询问给出长度为n的2个序列a,b
每次可以对1<i<n的ai进行操作,
操作后:
在这里插入图片描述
问能否通过若干次操作,使得序列a变成 b

输入格式

给出询问数T
第一行一个正整数n
第二行给出序列a
第三行给出序列b

输出格式

是否能转变,输出Yes或者No,每个询问对应一行

输入样例

样例1

1
4 
7 2 4 12
7 15 10 12

样例2

1
3
4 4 4
1 2 3

输出样例

样例1

Yes

样例2

No

解题思路

首先我们观察公式,通过移项可以得到以下两个式子:
a i ′ − a i + 1 = a i − 1 − a i a_i'-a_{i+1}=a_{i-1}-a_i aiai+1=ai1ai
a i ′ − a i − 1 = a i + 1 − a i a_i'-a{i-1}=a_{i+1}-a_i aiai1=ai+1ai
我们可以发现,这个操作就是把当前数的相邻的两个差分交换位置。
那么我们就求出这两个数列的差分,然后一一匹配就可以了,注意,输入样例比较大,所以要用快读,否则会超时

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath> 
#include<algorithm>
#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,1<<15,stdin),S==T))?EOF:*S++)
char buffer[1<<15],*S=buffer,*T=buffer;
using namespace std;
inline int read()//快读
{
    int m=0,n=1; 
	char ch;
	ch=getchar();
    while(ch<'0'||ch>'9')
	{  
	    if(ch=='-') 
		 n=-1;
	    ch=getchar();
	}
    while(ch>='0'&&ch<='9')
	{
	    m=m*10+ch-'0';
	    ch=getchar();
	}
    return m*n;
}
int a[100010],sum1[100010],sum2[100010];
inline bool pd(int a[],int b[],int n)//判断是否全等
{
	bool ok=1;
	for(int i=1;i<=n;i++)
	if(a[i]!=b[i])
	{
		ok=0;
		break;
	}
	if(ok==0) return false;
	return true;
}
int main()
{
	int t,n,k;
	t=read();
	for(int i=1;i<=t;i++)
	{
		n=read();
		a[1]=read();
		for(int j=2;j<=n;j++)
		{
			a[j]=read();
			sum1[j-1]=abs(a[j]-a[j-1]);//求出数列的差分
		}
		a[1]=read();
		for(int j=2;j<=n;j++)
		{
			a[j]=read();
			sum2[j-1]=abs(a[j]-a[j-1]);
		}
		sort(sum1+1,sum1+n);
		sort(sum2+1,sum2+n);
		if(pd(sum1,sum2,n-1)==true)
		 cout<<"Yes"<<endl;
		else cout<<"No"<<endl; 
	}
	return 0;
} 

谢谢阅读

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值