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(1n100) 的数组 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(0ai,bi100,ai100,bi100)
你可以对数组 a a a 修改不超过 100 100 100 次,每次可以选择一对 ( i , j ) ( 1 ≤ i , j ≤ n ) (i,j)(1 \\leq i,j \\leq n) (i,j)(1i,jn) ,使得 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(1n105) 个长度为 m ( 1 ≤ m ≤ 1 0 5 ) m(1 \\leq m \\leq 10^5) m(1m105) 的字符串。 ( n ⋅ m ≤ 1 0 5 ) (n \\cdot m \\leq 10^5) (nm105)
将其中的 n − 1 n-1 n1 个字符串组成 n − 1 2 \\fracn-12 2n1 对。每对中,选择某些位置,调换这两个字符串的对应位置字符。
现在直到初始的 n n n 个字符串,和配对修改后的 n − 1 n-1 n1 个字符串,求未配对的字符串。

题解

可以想到,对于任意位置 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(1n105) 个人排列在一条直线上,第 i i i 个人穿着 a i ( 1 ≤ a i ≤ 1 0 5 ) a_i(1 \\leq a_i \\leq 10^5) ai(1ai105) 号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(1n105) 的棋盘上完跳棋。初始某些位置上有棋子,其他位置上没棋子。
每次移动棋子时,可以选择位置 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 i1 上有棋子,位置 i − 2 i-2 i2 上没棋子,则可以移动到位置 i − 2 i-2 i2 上。

求从初始棋盘布局开始,可以通过操作得到多少种不同的棋盘布局。

题解

根据跳棋的移动规则,假设有三个相邻位置,前两个有棋子,最后一个没有棋子,即 ( 1 , 1 , 0 ) (1,1,0) (1,1,0) 的状态,那么最左边的棋子可以跳到最右边,变为 ( 0 , 1 , 1 ) (0,1,1) (0,1,1) 状态。
因此,可以将两个连续的棋子捆绑在一起,用 ( 2 ) (2) (2) 表示。这样原先的变化过程,就是

以上是关于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

Codeforces Round #732 (Div. 2) D. AquaMoon and Chess

Codeforces Round #732 (Div. 2)(D)