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(1≤si≤100) 且每位选手的水平不同。如果两位选手比赛,那么水平更高的选手会获胜。
比赛采用以下赛制:
- 第一位选手和第二位选手比赛
- 第三位选手和第四位选手比赛
- 上述两场比赛的胜者进行决赛
如果是水平最高的两位选手在决赛相遇,则称比赛是公平的。
请判断比赛是否公平。
题解
简单的模拟题,有多种方法可以实现:
- 直接判断决赛的两位选手的水平是否为最高与次高
- 判断 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(1≤n≤2000) 个元素的数组
a
(
1
≤
a
i
≤
1
0
5
)
a(1 \\leq a_i \\leq 10^5)
a(1≤ai≤105) 。
对于一对索引
i
,
j
i,j
i,j ,若
1
≤
i
<
j
≤
n
1 \\leq i < j \\leq n
1≤i<j≤n 且
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(N∗25) 。(其实不优化也完全没事,还多打了好多代码)
参考代码
#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(1≤∣s∣≤2⋅105) 。
如果一个字符串由 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](l≤i≤r) 也是漂亮的。
因此可以记录上一次的非法位置,那么非法位置之后的子串,都是漂亮的。
由于不确定 ? 变成 0 还是 1 ,因此不妨设:
- b e f 0 bef0 bef0 表示无法满足奇数位为 1 偶数位为 0 的前一个位置
- b e f 1 bef1 bef1 表示无法满足奇数位为 0 偶数位为 1 的前一个位置
如果连续子串右端点为 r r r ,则
- 左端点
l
∈
[
b
e
f
0
+
1
,
r
]
l \\in [bef0+1,r]
l∈[bef0
以上是关于Educational Codeforces Round 110 div.2 A~F题解的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 7 A
Educational Codeforces Round 7
Educational Codeforces Round 90
Educational Codeforces Round 33