Codeforces Round #732 div.2 A-E题解
Posted 欣君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #732 div.2 A-E题解相关的知识,希望对你有一定的参考价值。
div.2 视频讲解:BV1cU4y1G7CQ
div.1 视频讲解:TBD
div.2-A. AquaMoon and Two Arrays
题目大意
给定两个长度为
n
(
1
≤
n
≤
100
)
n(1 \\leq n \\leq 100)
n(1≤n≤100) 的数组
a
,
b
(
0
≤
a
i
,
b
i
≤
100
,
∑
a
i
≤
100
,
∑
b
i
≤
100
)
a,b(0 \\leq a_i,b_i \\leq 100,\\suma_i \\leq 100 ,\\sumb_i \\leq 100)
a,b(0≤ai,bi≤100,∑ai≤100,∑bi≤100) 。
你可以对数组
a
a
a 修改不超过
100
100
100 次,每次可以选择一对
(
i
,
j
)
(
1
≤
i
,
j
≤
n
)
(i,j)(1 \\leq i,j \\leq n)
(i,j)(1≤i,j≤n) ,使得
a
i
a_i
ai 增加
1
1
1 ,
a
j
a_j
aj 减少
1
1
1 。
求能否在
100
100
100 次操作内,将数组
a
a
a 修改为数组
b
b
b 。
题解
若
∑
a
i
≠
∑
b
i
\\suma_i \\neq \\sumb_i
∑ai=∑bi ,则不行,反之可以。
求操作序列时,可以将增加和减少单独考虑,减少代码复杂度。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=110;
int a[MAXN],b[MAXN],opi[MAXN],opj[MAXN];
int main()
int T,n,i,cnti,cntj,asum,bsum;
scanf("%d",&T);
while(T--)
scanf("%d",&n);
asum=bsum=0;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
asum+=a[i];
for(i=1;i<=n;i++)
scanf("%d",&b[i]);
bsum+=b[i];
if(asum!=bsum)
printf("-1\\n");
continue;
cnti=cntj=0;
for(i=1;i<=n;i++)
while(a[i]>b[i])
opi[cnti++]=i;
a[i]--;
while(a[i]<b[i])
opj[cntj++]=i;
a[i]++;
printf("%d\\n",cnti);
for(i=0;i<cnti;i++)
printf("%d %d\\n",opi[i],opj[i]);
div.2-B. AquaMoon and Stolen String
题目大意
有奇数
n
(
1
≤
n
≤
1
0
5
)
n(1 \\leq n \\leq 10^5)
n(1≤n≤105) 个长度为
m
(
1
≤
m
≤
1
0
5
)
m(1 \\leq m \\leq 10^5)
m(1≤m≤105) 的字符串。
(
n
⋅
m
≤
1
0
5
)
(n \\cdot m \\leq 10^5)
(n⋅m≤105)
将其中的
n
−
1
n-1
n−1 个字符串组成
n
−
1
2
\\fracn-12
2n−1 对。每对中,选择某些位置,调换这两个字符串的对应位置字符。
现在直到初始的
n
n
n 个字符串,和配对修改后的
n
−
1
n-1
n−1 个字符串,求未配对的字符串。
题解
可以想到,对于任意位置
i
i
i ,配对前
n
n
n 个字符串中的第
i
i
i 个位置的字符构成的多重集合,与配对修改后
n
n
n 个字符串中的第
i
i
i 个位置的字符构成的多重集合是一样的。以此统计配对前后每个位置上缺少哪个字符即可。
具体实现时,可以用求和或者异或简化代码。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=100100;
char s[MAXN];
int main()
int T,n,m,i,j;
char c;
scanf("%d",&T);
while(T--)
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
s[i]=0;
for(i=1;i<2*n;i++)
for(j=0;j<m;j++)
scanf(" %c",&c);
s[j]^=c;
for(i=0;i<m;i++)
printf("%c",s[i]);
puts("");
fflush(stdout);
div.2-C/div.1-A. AquaMoon and Strange Sort
题目大意
有
n
(
1
≤
n
≤
1
0
5
)
n(1 \\leq n \\leq 10^5)
n(1≤n≤105) 个人排列在一条直线上,第
i
i
i 个人穿着
a
i
(
1
≤
a
i
≤
1
0
5
)
a_i(1 \\leq a_i \\leq 10^5)
ai(1≤ai≤105) 号T恤,并且初始时,每个人都朝右。
你可以任意次数改变他们的位置。每次选择两个相邻的人,交换他们的位置,并让他们的朝向相反的方向。
求能否让所有人的T恤编号从左到右为不下降序列,且每个人都朝右。
题解
如果希望使得修改后每个人朝向不变,则每个人的移动步数,均为
2
2
2 的倍数。以此若一个人原先在奇数位置,修改后也在奇数位置。偶数同理。
将位置按奇偶分为两个多重集合,则排序前后,两个集合内的元素应该保持不变。若不能,则无解。
实现时,分别构建两个计数数组对奇偶位置的T恤计数即可。
参考代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN=100100;
int a[MAXN],num[2][MAXN];
int main()
int T,n,i,flag;
scanf("%d",&T);
while(T--)
memset(num,0,sizeof(num));
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
num[i&1][a[i]]++;
sort(a+1,a+n+1);
flag=1;
for(i=1;i<=n;i++)
if(!num[i&1][a[i]])
flag=0;
break;
num[i&1][a[i]]--;
if(flag)
printf("YES\\n");
else
printf("NO\\n");
div.2-D/div.1-B. AquaMoon and Chess
题目大意
在
1
×
n
(
1
≤
n
≤
1
0
5
)
1 \\times n(1 \\leq n \\leq 10^5)
1×n(1≤n≤105) 的棋盘上完跳棋。初始某些位置上有棋子,其他位置上没棋子。
每次移动棋子时,可以选择位置
i
i
i 上的棋子,然后进行以下操作之一:
- 若位置 i + 1 i+1 i+1 上有棋子,位置 i + 2 i+2 i+2 上没棋子,则可以移动到位置 i + 2 i+2 i+2 上。
- 若位置 i − 1 i-1 i−1 上有棋子,位置 i − 2 i-2 i−2 上没棋子,则可以移动到位置 i − 2 i-2 i−2 上。
求从初始棋盘布局开始,可以通过操作得到多少种不同的棋盘布局。
题解
根据跳棋的移动规则,假设有三个相邻位置,前两个有棋子,最后一个没有棋子,即
(
1
,
1
,
0
)
(1,1,0)
(1,1,0) 的状态,那么最左边的棋子可以跳到最右边,变为
(
0
,
1
,
1
)
(0,1,1)
(0,1,1) 状态。 以上是关于Codeforces Round #732 div.2 A-E题解的主要内容,如果未能解决你的问题,请参考以下文章 Codeforces Round #732 (Div. 1&&Div. 2) Codeforces Round #732 div.2 A-E题解 Codeforces Round #732 div.2 A-E题解 Codeforces Round #732 (Div. 2) D. AquaMoon and Chess
因此,可以将两个连续的棋子捆绑在一起,用
(
2
)
(2)
(2) 表示。这样原先的变化过程,就是