许可优化
产品
解决方案
服务支持
关于
软件库
当前位置:服务支持 >  软件文章 >  Codeforces Round #825 (Div. 2):精彩赛题回顾

Codeforces Round #825 (Div. 2):精彩赛题回顾

阅读数 7
点赞 0
article_banner

A - Make A Equal to B

分类讨论:

  • 1.进行一次排序
  • 2.不进行一次排序

然后两种情况取最小值。

情况一:使得 A ,B 数组内 , 0,1 个数相等即可, Ans1= (方案一操作次数 +1)

情况二:使得 A ,B 数组内 , 0,1 个数每一位相等即可, Ans2= (方案二操作次数)

综上:答案为 (Ans1 , Ans2)_{min}

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;
 
#define ri register int
 
int T;
int n;
int a[1000050];
int b[1000050];
 
int main()
{
	int cnta0,cnta1,cntb0,cntb1;
	scanf("%d",&T);
	while(T--)
	{
		int ans=0,ansa=0;
		cnta1=cnta0=cntb0=cntb1=0;
		scanf("%d",&n);
		for(ri i=1; i<=n; ++i)
		{
			scanf("%d",&a[i]);
			if(a[i]==0)
			{
				cnta0++;
			}
			else
			{
				cnta1++;
			}
		}
		for(ri i=1; i<=n; ++i)
		{
			scanf("%d",&b[i]);
			if(b[i]==0)
			{
				cntb0++;
			}
			else
			{
				cntb1++;
			}
		}
		int det=abs(cnta1-cntb1);
		for(register int i=1; i<=n; ++i)
		{
			if(det==0)
			{
				break;
			}
			if(a[i]!=b[i])
			{
				det--;
				ans++;
			}
		}
		ans++;
		//
		for(register int i=1; i<=n; ++i)
		{
			if(a[i]!=b[i])
			{
				ansa++;
			}
		}
		cout<<min(ansa,ans)<<endl;
	}
}

B - Playing with GCD

构造题,考虑 b[1] ,最优情况为 b[1]==a[1] ,因为使得 b[2] 的取值情况更多。

为接下来的数据留出更多的机会去选择 , (这里实际上就是贪心策略)。

\because a_i = gcd(b_i,b_{i+1}) 且 a_{i+1} = gcd(b_{i+1},b_{i+2})

\therefore b_{i+1}= gcd(a_i,a_{i+1})

又 \because gcd(b_i,b_{i+1}) =a_i

\therefore 有判断条件:

if(gcd(b_i,b_{i+1}) \ne a_i) puts("NO");

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;

#define ri register int

int T;
int n;
int a[1000050];
int b[1000050];

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(ri i=1;i<=n;++i)
		{
			scanf("%d",&a[i]);
		}
		bool ret=1;
		b[1]=a[1];
		b[n+1]=b[n];
		
		for(ri i=2;i<=n;++i)
		{
			b[i]=a[i-1]*a[i]/__gcd(a[i],a[i-1]);
			if(__gcd(b[i],b[i-1])!=a[i-1])
			{
				ret=0;
				break;
			}
		}
		if(ret==0)
		{
			puts("NO");
		}
		else
		{
			puts("YES");
		}
	}
}

C1 - Good Subarrays (Easy Version)

这题方法多样,这里介绍其中两种 1.dp 2.双指针

  1. dp

考虑 f_i 代表以 i 结尾的 “好数组个数”。

于是考虑前一位 f_{i-1} 能否继承 ?

若能 ,即 f_{i-1}+1 继承 。

否则 ,考虑以 i 为结尾的连续区间的个数 ,易知有 a[i] 个新子区间 。

则有状态转移方程 : f[i] = min(f[i-1]+1,a[i]);

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;

int n,T;
int a[200005];
int f[200005];

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
		{
			scanf("%d",&a[i]);
			f[i]=0;
		}
		f[1]=1;
		long long ans=0;
		for(int i=1;i<=n;++i)
		{
			f[i]=min(f[i-1]+1,a[i]);
			ans+=f[i];
		}
		cout<<ans<<endl;
	} 
}


2.双指针

模拟两个指针 l,r

考虑区间 [l,r] 问题 ,

a[r]<r-l+1 , 则不满足题目条件。

则左边界偏小, l++ ;

反之, r++

注意循环退出的边界情况

  • 1. l > n || r>n , break ;
  • 2. l>r , break;
#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;

#define int long long
#define ri register int

int T;
int n;
int a[200050];

signed main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(ri i=1;i<=n;++i)
		{
			scanf("%d",&a[i]);
		}
		int l=1;
		int r=1;
		int res=0;
		while(l<=r)
		{
			if(l>n||r>n)
			{
				break;
			}
			while(a[r]<r-l+1)
			{
				++l;
			}
			res=res+r-l;
			r++;
		}
		cout<<res+n<<endl;
	}
}


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删
相关文章
QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空