题解纠正
  • 板块灌水区
  • 楼主Lijiangjun4
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/7/22 18:58
  • 上次更新2024/7/22 20:06:41
查看原帖
题解纠正
1274736
Lijiangjun4楼主2024/7/22 18:58

我发的题解因“未按规定排版”被打回了,哪个大牛帮忙看看错在哪了,悬赏一个关注(通过后生效)

题目:CF1980D GCD-sequence

题解内容:

解题思路

解决这题需要分以下步骤:

  1. 输入 a 数组;
  2. 通过欧几里得算法编写出 long long gcd(long long x,long long y) 函数来处理b数组;
  3. 预处理两个 bool 数组 flag1flag1 和 flag2flag2,flag1iflag1_i 表示 b1b_1 ~ bib_i 是否不降,flag2iflag2_i 表示 bib_i ~ bn−1b_{n-1} 是否不降;
  4. 遍历每个 aia_i ,判断去掉 aia_i 后:
    a. b 数组左半部分是否不降( flag1[i-2] );
    b. b 数组右半部分是否不降( flag2[i+1] );
    c. 新产生的 gcd(a[i-1],a[i+1]) 是否合法。

注意边界特判。 不理解的,可以看图。(纠正:图片左下角的 flag[i-2] 应改为 flag1[i-2] 。)

AC Code

#include<iostream>
#include<cstring>
using namespace std;
long long a[200005],b[200005],n;
long long gcd(long long x,long long y)
{
	//欧几里得算法求最大公因数 
	return y==0?x:gcd(y,x%y);
}
bool check()
{
	bool flag1[200005],flag2[200005];//flag1[i]表示从b[1]到b[i]是否不降,flag2[i]表示从b[i]到b[n-1]是否不降
	b[n]=2e9;
	for(int i=1;i<n;i++)
	{
		b[i]=gcd(a[i],a[i+1]);//预处理b[i] 
	}
	flag1[0]=true;
	for(int i=1;i<n;i++)
	{
		flag1[i]=flag1[i-1]&&b[i]>=b[i-1];//计算前缀 
	}
	flag2[n-1]=flag2[n]=true;
	for(int i=n-2;i>=1;i--)
	{
		flag2[i]=flag2[i+1]&&b[i]<=b[i+1];//计算后缀 
	}
	int ans=flag1[n-2]|flag2[2];//特判 
	for(int i=2;i<n;i++)
	{
		int k=gcd(a[i-1],a[i+1]);
		ans|=(
		flag1[i-2]&&//前缀
		flag2[i+1]&&//后缀
		k>=b[i-2]&&
		k<=b[i+1]//匹配左右 
		);
	}
	return ans;
}
int main()
{
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		if(check())
		{
			cout<<"YES\n";
		}
		else
		{
			cout<<"NO\n";
		}
	}
	return 0; 
}

一定要小心第 31~37 行的写法!

2024/7/22 18:58
加载中...