Bootstrap

9.11 codeforces Div 2

9.11 Div 2

Dashboard - Codeforces Round 969 (Div. 2) - Codeforces

A. Dora’s Set(删除三个互质数)

集合s是l,r之间的数字

  • 从集合 s 中选择三个不同的整数 a 、 b 和 c ,使得 gcd(a,b)=gcd(b,c)=gcd(a,c)=1 。

  • 然后,从集合 ss 中删除这三个整数。

思路

由题意知,需要尽可能多的组成三个互质的数字。必然不能存在两个偶数,所以每个组合至少两个奇数

由于集合s是连续序列,直接取相邻的三个数(两奇一偶),因而计算奇数个数,除以2就是答案。

代码

void solve()
{   int l,r;
	cin>>l>>r;
	int n=r-l+1;
	int j=n/2;
	if(n%2!=0) j=j+l%2;
	cout<<j/2<<'\n';
}

B. Index and Maximum Value(范围加减1求max)

对于一个整数数组,数字在 [ l , r ] [l,r] [l,r]范围内,进行+1或-1.每操作后,输出最大值。

审题不清,刚开始以为下标在某范围内,进行±,但平常也用不上算法,后来开始写ST,模板没记住,又废了好一会儿。

思路

看似复杂,实则只需考虑max,是否在范围内。

若不在范围内,顶多出现max-1变成了max ,最大值依旧为max

若在范围内,max++,便是答案

若不在范围内,max

在范围内,max—

代码

void solve()
{	int n,m,mx=0;
	char x;
	cin>>n>>m;
	fir(i,1,n)
	{
		cin>>a[i];
		if(a[i]>mx)
		mx=a[i];
	}
	 
	while(m--)
	{int l,r;
		cin>>x>>l>>r;
		if(mx>=l&&mx<=r)
		{ if(x=='+') mx++;
		  else mx--;
		}	 
		cout<<mx<<' ';
	}
	cout<<'\n';
}

C. Dora and C++(加a/b,最小化极差)

一个数组可以选择对某个数字+a/b,进行无限次操作,得到最小极差

思路

​ 我的整体思路没错,计算一个C,数组对C取模,将结果围成一个圈,两种转圈方法,取最小的。

两个细节有问题

  • c我简单的以为是min(a,b,|a-b|),实在太疏忽了。

    比如(15,9),可以变成(15,18),此时他们的差值为3而不是6。这样太武断了,且没有说服力很强的论证,看起来就不像答案。

  • 对于第二中转圈方法,我将小于C/2的 数字+C,最后用max-min

    比如1 4 6 8 9,c=10

    此时为(14-6=8),这样并不是最优的,(11-4=7才是)。之前遇到过相似题,当时按这个思路写对了,复杂。

    问题应该这样解决:

  • c=__gcd(a,b)

最终数组肯定是由多个a,b相加得到,可以表示为 c i = f a + f b + c i c_i=fa+fb+c_i ci=fa+fb+ci

c i = k c + b c_i=kc+b ci=kc+b

  • w[i-1]+c-w[i]

这样将每一个i,作为开端,前面的数字作为末尾。遍历得出最小

最终答案有理有据,而我的武断猜想也很重要

代码

void solve()
{
	int n,a,b,ans;
	cin>>n>>a>>b;
	int c=__gcd(a,b);
	fir(i,1,n)
	{
		cin>>w[i];
		w[i]%=c;
	}
	sort(w,w+n+1);
	ans=w[n]-w[1];//1
	fir(i,1,n)
	{
		ans=min(ans,w[i-1]+c-w[i]);//2
	}
	cout<<ans<<'\n';
}
;