Educational Codeforces Round 110 div.2 A~F题解

Posted 欣君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 110 div.2 A~F题解相关的知识,希望对你有一定的参考价值。

视频讲解:BV1254y137Rn

A. Fair Playoff

题目大意

4 4 4 位选手参加比赛,第 i i i 位选手的水平为 s i ( 1 ≤ s i ≤ 100 ) s_i(1 \\leq s_i \\leq 100) si(1si100) 且每位选手的水平不同。如果两位选手比赛,那么水平更高的选手会获胜。
比赛采用以下赛制:

  • 第一位选手和第二位选手比赛
  • 第三位选手和第四位选手比赛
  • 上述两场比赛的胜者进行决赛

如果是水平最高的两位选手在决赛相遇,则称比赛是公平的。
请判断比赛是否公平。

题解

简单的模拟题,有多种方法可以实现:

  • 直接判断决赛的两位选手的水平是否为最高与次高
  • 判断 m a x ( s 1 , s 2 ) > m i n ( s 3 , s 4 ) max(s_1,s_2)>min(s_3,s_4) max(s1,s2)>min(s3,s4) m a x ( s 3 , s 4 ) > m i n ( s 1 , s 2 ) max(s_3,s_4)>min(s_1,s_2) max(s3,s4)>min(s1,s2) 是否都成立
  • 判断 m i n ( m a x ( a , b ) , m a x ( c , d ) ) ≥ m a x ( m i n ( a , b ) , m i n ( c , d ) ) min(max(a,b),max(c,d)) \\geq max(min(a,b),min(c,d)) min(max(a,b),max(c,d))max(min(a,b),min(c,d)) 是否成立

参考代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int T,i,s[10],b[10];
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d%d",&s[1],&s[2],&s[3],&s[4]);
		for(i=1;i<=4;i++)
			b[i]=s[i];
		sort(b+1,b+5);
		if(max(s[1],s[2])+max(s[3],s[4])==b[3]+b[4])
			printf("YES\\n");
		else
			printf("NO\\n");
	}
}

B. Array Reodering

题目大意

给定包含 n ( 1 ≤ n ≤ 2000 ) n(1 \\leq n \\leq 2000) n(1n2000) 个元素的数组 a ( 1 ≤ a i ≤ 1 0 5 ) a(1 \\leq a_i \\leq 10^5) a(1ai105)
对于一对索引 i , j i,j i,j ,若 1 ≤ i < j ≤ n 1 \\leq i < j \\leq n 1i<jn g c d ( a i , 2 a j ) > 1 gcd(a_i,2a_j)>1 gcd(ai,2aj)>1 ,则称其为好的索引对。
现在你可以对数组进行重新排列,求最大的好索引对数量。

题解

如果 a i a_i ai 是偶数,那么必定满足 g c d ( a i , 2 a j ) > 1 gcd(a_i,2a_j)>1 gcd(ai,2aj)>1 ,因此在重新排列时,应该将偶数都排在前面,奇数排在后面。
对于奇数的 a i , a j a_i,a_j ai,aj g c d ( a i , 2 a j ) = g c d ( a i , a j ) gcd(a_i,2a_j)=gcd(a_i,a_j) gcd(ai,2aj)=gcd(ai,aj) ,可以直接用两重循环在 O ( N 2 ) O(N^2) O(N2) 复杂度内求解。
也可以对每个数分解质因数后,用容斥处理。由于分解质因数后 a i a_i ai 的质因数个数最多为 5 5 5 个,因此复杂度可以优化到 O ( N ∗ 2 5 ) O(N*2^5) O(N25) 。(其实不优化也完全没事,还多打了好多代码)

参考代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int MAXN=100100;
int npri[MAXN],sum[MAXN],a[MAXN];
vector<int> fac[MAXN];

int main()
{
	int i,j,k,T,n,limit,tmp,num1,cnt,x;
	ll ans;
	for(i=2;i<MAXN;i++)
	{
		if(npri[i])
			continue;
		fac[i].push_back(i);
		for(j=i+i;j<MAXN;j+=i)
		{
			npri[j]=1;
			fac[j].push_back(i);
		}
	}
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		cnt=0;
		for(i=1;i<=n;i++)
		{
			scanf("%d",&x);
			if(x%2)
				a[++cnt]=x;
		}
		ans=1ll*cnt*(n-cnt)+1ll*(n-cnt)*(n-cnt-1)/2;
		sort(a+1,a+cnt+1);
		memset(sum,0,sizeof(sum));
		for(i=1;i<=cnt;i++)
		{
			limit=1<<(fac[a[i]].size());
			for(j=1;j<limit;j++)
			{
				tmp=1;
				num1=0;
				for(k=0;k<fac[a[i]].size();k++)
				{
					if((j>>k)&1)
					{
						num1++;
						tmp*=fac[a[i]][k];
					}
				}
				if(num1)
					ans+=sum[tmp];
				else
					ans-=sum[tmp];
				sum[tmp]++;
			}
		}
		printf("%lld\\n",ans);
	}
}

C. Unstable String

题目大意

给定一个仅由 0,1 和 ? 组成的字符串 s ( 1 ≤ ∣ s ∣ ≤ 2 ⋅ 1 0 5 ) s(1 \\leq |s| \\leq 2 \\cdot 10^5) s(1s2105)
如果一个字符串由 0 和 1 组成,且相邻字符不同,则称其为不稳定字符串。
如果一个字符串由 0,1 和 ? 组成,且可以通过替换 ? 为 0 或 1 (每个 ? 可以替换为不同的字符),则称其为漂亮字符串。
求字符串 s s s 有多少个漂亮的连续子串。

题解

如果子串 s [ l , r ] s[l,r] s[l,r] 是漂亮的,那么 s [ i , r ] ( l ≤ i ≤ r ) s[i,r](l \\leq i \\leq r) s[i,r](lir) 也是漂亮的。
因此可以记录上一次的非法位置,那么非法位置之后的子串,都是漂亮的。
由于不确定 ? 变成 0 还是 1 ,因此不妨设:

  • b e f 0 bef0 bef0 表示无法满足奇数位为 1 偶数位为 0 的前一个位置
  • b e f 1 bef1 bef1 表示无法满足奇数位为 0 偶数位为 1 的前一个位置

如果连续子串右端点为 r r r ,则