【Codeforces】Codeforces Round #828 (Div. 3) 赛中过题记录A-E1

227 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

【Codeforces】Codeforces Round #828 (Div. 3) 赛中过题记录A-E1

A Number Replacement

题目大意

给定一个含有 nn 个元素的数组 a1,a2,...,ana_1,a_2,...,a_n 通过过程转换为小写英文字母数组:

如果数组中至少有一个数字:

  • 从数组中选择任意数字 xx,以及任意小写字母 yy
  • 将数组中所有数字 xx 替换为字母 yy

输出数组能否被转变为给定的字符串 b1,b2,...,bnb_1,b_2,...,b_n

思路

遍历数组: 如果 aia_i 未被转换成小写字母,将数组中所有等于 aia_i 的元素其转变为 bib_i
否则如果 aia_i 转换成的小写字母不等于 bib_i,输出NO

代码

#include <bits/stdc++.h>
using namespace std;
using LL=long long;
typedef pair<int,int> PII;
const int N=500001;
const LL mod=1000000007;
vector<int> e[N];
int f[N],x,y,z;
int n,m,k;
void bcjInit() {for (int i=1;i<=n;++i) f[i]=i;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
LL gcd(LL x,LL y) {return y==0?x:gcd(y,x%y);}
int a[N];
char ch[N],v[51];
int solve()
{
	memset(v,0,sizeof(v));
	scanf("%d",&n);
	for (int i=1;i<=n;++i) scanf("%d",&a[i]);
	for (int i=1;i<=n;++i) cin>>ch[i];
	for (int i=1;i<=n;++i)
	{
		if (v[a[i]]&&v[a[i]]!=ch[i]) return 0;
		v[a[i]]=ch[i];
	}
	return 1;
}
int main()
{
	int T=1;
	for (scanf("%d",&T);T--;)
                if (solve()) printf("YES\n");
                else printf("NO\n");
	return 0;
}

B Even-Odd Increments

题目大意

给定 nn 个整数 a1,a2,...,ana_1,a_2,...,a_n。给出 qq 个查询,分为以下两种:

  • 0 xj0\ x_j”:令数组中所有值为偶数的元素增加 xjx_j
  • 1 xj1\ x_j”:令数组中所有值为奇数的元素增加 xjx_j

对于每个查询,输出操作后数组中所有元素之和。

思路

维护所有元素之和 sumsum,偶元素的数量 cnt0cnt0,奇元素的数量 cnt1cnt1

  • 0 操作会使得 sumsum 增加 cnt0×xjcnt0\times x_j。如果 xjx_j 是奇数,将会把数组中所有偶元素变为奇元素。
  • 1 操作会使得 sumsum 增加 cnt1×xjcnt1\times x_j。如果 xjx_j 是奇数,将会把数组中所有奇元素变为偶元素。

依次处理询问并输出 sumsum

代码

#include <bits/stdc++.h>
using namespace std;
using LL=long long;
const int N=500001;
const LL mod=1000000007;
vector<int> e[N];
int f[N],x,y,z;
int n,m,k;
void bcjInit() {for (int i=1;i<=n;++i) f[i]=i;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
LL gcd(LL x,LL y) {return y==0?x:gcd(y,x%y);}
int a[N];
char ch[N],v[51];
int solve()
{
	long long x,sum=0;
	int cnt0=0,cnt1=0,opt;
	memset(v,0,sizeof(v));
	scanf("%d",&n);
	scanf("%d",&m);
	for (int i=1;i<=n;++i)
	{
		scanf("%lld",&x);
		if (x%2) cnt1++;
		else cnt0++;
		sum+=x;
	}
	while (m--)
	{
		scanf("%d",&opt);
		scanf("%lld",&x);
		if (opt)
		{
			sum+=cnt1*x;
			if (x%2) cnt0+=cnt1,cnt1=0;
		}
		else
		{
			sum+=cnt0*x;
			if (x%2) cnt1+=cnt0,cnt0=0;
		}
		printf("%lld\n",sum);
	}
	return 1;
}
int main()
{
	int T=1;
	for (scanf("%d",&T);T--;) solve();
	return 0;
}

C Traffic Light

题目大意

给定一串仅有‘r’、‘y’、‘g’构成的字符串 s1,s2,...,sns_1,s_2,...,s_n

‘r’表示红灯亮一秒,‘y’表示黄灯亮一秒,‘g’表示绿灯亮一秒。则字符串表示某个十字路口的交通信号灯闪烁依次为 s1,s2,...,sn,s1,s2,...,sn,s1,s2,...,sn,...s_1,s_2,...,s_n,s_1,s_2,...,s_n,s_1,s_2,...,s_n,...

假设当前交通信号灯显示的颜色为 colcol,问至少多少秒之内交通信号灯一定显示过绿色。

思路

遍历字符串,对每个显示颜色为 colcol 的位置暴力找到其下一个绿色信号多少秒后会出现,取最大值输出。

可以把字符串复制一遍放在其后,方便处理循环。

代码

#include <bits/stdc++.h>
using namespace std;
using LL=long long;
typedef pair<int,int> PII;
const int N=500001;
const LL mod=1000000007;
vector<int> e[N];
int f[N],x,y,z;
int n,m,k;
void bcjInit() {for (int i=1;i<=n;++i) f[i]=i;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
LL gcd(LL x,LL y) {return y==0?x:gcd(y,x%y);}
char ch[N],col;
int solve()
{
	int x,ans=0;
	int cnt0=0,cnt1=0,opt;
	scanf("%d",&n);
	cin>>col;
	for (int i=1;i<=n;++i)
	{
		cin>>ch[i];
		ch[n+i]=ch[i];
	}
	if (col=='g')
	{
		printf("0\n");
		return 0;
	}
	for (int i=1,j=0;i<=n;++i)
	{
		if (ch[i]!=col) continue;
		for (j=max(j,i);ch[j]!='g';j++);
		ans=max(ans,j-i);
	}
	printf("%d\n",ans);
	return 1;
}
int main()
{
	int T=1;
	for (scanf("%d",&T);T--;) solve();
	return 0;
}

D Divisibility by 2^n

题目大意

给定一个正整数数组 a1,a2,...,ana_1,a_2,...,a_n。可以执行若干次下述操作:

  • 选择任意数组下标 ii,并用 ai×ia_i\times i 替换 aia_i

输出使数组中所有元素的乘积可以被 2×n2\times n 整除所需执行的最少操作数。无解输出 -1。

思路

Cnt[i]Cnt[i] 表示 ii 的质因数分解中有多少个 2。

则原问题变为从 Cnt[1],Cnt[2],...,Cnt[n]Cnt[1],Cnt[2],...,Cnt[n] 中选择尽可能少的数使得被选择的数之和大于 nCnt[a1×a2×...×an]n-Cnt[a_1\times a_2\times ...\times a_n]

代码

#include <bits/stdc++.h>
#define nn printf("NO\n")
#define yy printf("YES\n")
#define nnn printf("No\n")
#define yyy printf("Yes\n")
using namespace std;
using LL=long long;
typedef pair<int,int> PII;
const int N=500001;
const LL mod=1000000007;
//const LL mod=998244353;
vector<int> e[N];
int f[N],x,y,z;
int n,m,k;
void bcjInit() {for (int i=1;i<=n;++i) f[i]=i;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
LL gcd(LL x,LL y) {return y==0?x:gcd(y,x%y);}
int cnt[N];
int cmp(int a,int b)
{
	return a>b;
}
int solve()
{
	int ans=0;
	scanf("%d",&n);
	long long sum=0;
	for (int i=1,x;i<=n;++i)
	{
		scanf("%d",&x);
		while (x%2==0)
		{
			sum++;
			x/=2;
		}
		cnt[i]=0;
		x=i;
		while (x%2==0)
		{
			cnt[i]++;
			x/=2;
		}
	}
	sort(cnt+1,cnt+1+n,cmp);
	for (int i=0;i<=n;++i)
	{
		sum+=cnt[i];
		if (sum>=n)
		{
			printf("%d\n",i);
			return 0;
		}
	}
	printf("-1\n");
	return 1;
}
int main()
{
	int T=1;
	for (scanf("%d",&T);T--;) solve();
	return 0;
}

E1 Divisible Numbers (easy version)

题目大意

给定 4 个正整数 a,b,c,da,b,c,d,其中 a<ca<cb<db<d。找出满足下列条件的任意一对数 xxyy

  • a<xc,b<yda<x\le c, b<y\le d,
  • a×bx×ya\times b\mid x\times y

保证 1a,b,c,d1051\le a,b,c,d\le 10^5

思路

范围比较小,xx 暴力尝试取 a+1a+1cc 之间所有的值,看是否有合法的 yy

代码

#include <bits/stdc++.h>
#define nn printf("NO\n")
#define yy printf("YES\n")
#define nnn printf("No\n")
#define yyy printf("Yes\n")
using namespace std;
using LL=long long;
typedef pair<int,int> PII;
const int N=500001;
const LL mod=1000000007;
//const LL mod=998244353;
vector<int> e[N];
int f[N],x,y,z;
int n,m,k;
void bcjInit() {for (int i=1;i<=n;++i) f[i]=i;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
LL gcd(LL x,LL y) {return y==0?x:gcd(y,x%y);}
long long a,b,c,d;
int solve()
{
	cin>>a>>b>>c>>d;
	for (long long x=a+1;x<=c;++x)
	{
		long long y=a*b/gcd(a*b,x);
		y=(b/y+1)*y;
		if (y<=d)
		{
			cout<<x<<" "<<y<<"\n";
			return 0;
		}
	}
	printf("-1 -1\n");
	return 1;
//	scanf("%d",&k);
}
int main()
{
	int T=1;
	for (scanf("%d",&T);T--;) solve();
	return 0;
}