Codeforces Round #724 div.2 A-F题解

Posted 欣君

tags:

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

视频讲解:BV18o4y1y74h

A. Omkar and Bad Story

题目大意

如果数组 b b b 中任意两个元素之差的绝对值 ∣ b i − b j ∣ |b_i-b_j| bibj 都在数组 b b b 中至少出现一次,则称数组 b b b 是好数组。
给定一个包含 n ( 2 ≤ n ≤ 100 ) n(2 \\leq n \\leq 100) n(2n100) 的数组 a ( − 100 ≤ a i ≤ 100 ) a(-100 \\leq a_i \\leq 100) a(100ai100) ,问是否能向 a a a 中添加整数,使其变成一个不超过 300 300 300 个元素的好数组。

题解

好数组中没有负数。否则最大值减去负数,会得到一个更大的值。基于此,可以判断 a a a 数组能否变成一个好数组。
由于 a i ≤ 100 a_i \\leq 100 ai100 ,因此包含元素 0 , 1 , 2 , 3 , . . . , m a x { a i } 0,1,2,3,...,max\\{a_i\\} 0,1,2,3,...,max{ai} 的数组,必定可以由 a a a 添加新元素构成,且是一个好数组。

参考代码

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

int gcd(int a,int b)
{
	return a%b?gcd(b,a%b):b;
}

int main()
{
	int T,n,i,a[110];
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
		sort(a+1,a+n+1);
		if(a[1]<0)
		{
			printf("NO\\n");
			continue;
		}
		printf("YES\\n%d\\n",a[n]+1);
		for(i=0;i<=a[n];i++)
			printf("%d ",i);
		puts("");
	}
}

B. Prinzessin der Verurteilung

题目大意

给定一个长度为 n ( 1 ≤ n ≤ 1000 ) n(1 \\leq n \\leq 1000) n(1n1000) 的由小写字母构成的字符串 s s s ,求其 M E X MEX MEX
一个字符串的 M E X MEX MEX 值,等于不在其连续子串中出现的最短且字典序最小的由小写字母构成的字符串。

题解

长度为 1 1 1 的由小写字母组成的字符串有 26 26 26 种;
长度为 1 1 1 的由小写字母组成的字符串有 2 6 2 = 676 26^2=676 262=676 种;
长度为 1 1 1 的由小写字母组成的字符串有 2 6 3 = 17576 26^3=17576 263=17576 种;
由于字符串长度不超过 1000 1000 1000 ,因此其 M E X MEX MEX 必定不超过 3 3 3 个字符,不妨全部枚举后线性查找。
时间复杂度 O ( G 3 N ) O(G^3N) O(G3N) G = 26 , N ≤ 1000 G=26,N \\leq 1000 G=26,N1000 ,最大不超过 2 ⋅ 1 0 7 2 \\cdot 10^7 2107

参考代码

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

void add(string &s)
{
	int inc=1;
	for(int i=s.length()-1;i>=0&&inc;i--)
	{
		if(s[i]+inc>'z')
			s[i]='a';
		else
		{
			s[i]++;
			inc=0;
		}
	}
	if(inc)
		s='a'+s;
}

int main()
{
	int T,n;
	string str,s;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		cin>>str;
		for(s="a";str.find(s)!=string::npos;add(s));
		cout<<s<<endl;
	}
}

C. Diluc and Kaeya

题目大意

给定一个由 ‘D’ 和 ‘K’ 两种字符组成的字符串,求最多可以将其分为多少个连续子串,使其每个子串内的 ‘D’ 与 ‘K’ 数量比相同。

题解

易得每个子串内的数量比,等于整个字符串的数量比。
D s u m i Dsum_i Dsumi K s u m i Ksum_i Ksumi 分别表示前 i i i 个字符中 ‘D’ 的数量和 ‘K’ 的数量。
d p i dp_i dpi 表示前 i i i 个字符最多可以分为多少子串,则有
d p i = m a x { d p j } + 1 dp_i=max \\{dp_j\\}+1 dpi=max{dpj}+1

( j ≤ i    & &    D s u m i : K s u m i = D s u m j : K s u m j ) (j \\leq i \\; \\&\\& \\; Dsum_i:Ksum_i=Dsum_j:Ksum_j) (ji&&Dsumi:Ksumi=Dsumj:Ksumj)

实现时,由于同一比例下,越靠后的 d p j dp_j dpj 越大,因此可以用 map 维护某一比例的上一个 d p j dp_j dpj 值。

参考代码

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

const int MAXN=500500;
int dp[MAXN],dnum[MAXN],knum[MAXN];
map<pair<int,int>,int> mp;

int gcd(int x,int y)
{
	if(y==0)
		return x;
	return x%y?gcd(y,x%y):y;
}

int main()
{
	int T,n,i,g;
	char c;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		dnum[0]=knum[0]=0;
		for(i=1;i<=n;i++)
		{
			scanf(" %c",&c);
			dnum[i]=dnum[i-1]+(c=='D'?1:0);
			knum[i]=knum[i-1]+(c=='K'?1:0);
		}
		mp.clear();
		for(i=1;i<=n;i++)
		{
			g=gcd(dnum[i],knum[i]);
			dp[i]=mp[make_pair(dnum[i]/g,knum[i]/g)]+1;
			mp[make_pair(dnum[i]/g,knum[i]/g)]=dp[i];
		}
		for(i=1;i<=n;i++)
			printf("%d ",dp[i]);
		puts("");
	}
}

D. Omkar and Medians

题目大意

给定一个包含 n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n(1 \\leq n \\leq 2 \\cdot 10^5) n(1n2105) 个整数的数组 b ( − 1 0 9 ≤ b i ≤ 1 0 9 ) b(-10^9 \\leq b_i \\leq 10^9) b(109b以上是关于Codeforces Round #724 div.2 A-F题解的主要内容,如果未能解决你的问题,请参考以下文章

E. Omkar and Forest——Codeforces Round #724 (Div. 2)

E. Omkar and Forest——Codeforces Round #724 (Div. 2)

F. Omkar and Akmar游戏,组合,逆元—— Codeforces Round #724 (Div. 2)

Codeforces Round #724 (Div. 2)(CD)

Codeforces Round #724 div.2 A-F题解

Codeforces Round #724 div.2 A-F题解