本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
【Codeforces】Codeforces Round #828 (Div. 3) 赛中过题记录A-E1
A Number Replacement
题目大意
给定一个含有 个元素的数组 通过过程转换为小写英文字母数组:
如果数组中至少有一个数字:
- 从数组中选择任意数字 ,以及任意小写字母 。
- 将数组中所有数字 替换为字母 。
输出数组能否被转变为给定的字符串 。
思路
遍历数组:
如果 未被转换成小写字母,将数组中所有等于 的元素其转变为 。
否则如果 转换成的小写字母不等于 ,输出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
题目大意
给定 个整数 。给出 个查询,分为以下两种:
- “”:令数组中所有值为偶数的元素增加 。
- “”:令数组中所有值为奇数的元素增加 。
对于每个查询,输出操作后数组中所有元素之和。
思路
维护所有元素之和 ,偶元素的数量 ,奇元素的数量 。
- 0 操作会使得 增加 。如果 是奇数,将会把数组中所有偶元素变为奇元素。
- 1 操作会使得 增加 。如果 是奇数,将会把数组中所有奇元素变为偶元素。
依次处理询问并输出 。
代码
#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’构成的字符串 。
‘r’表示红灯亮一秒,‘y’表示黄灯亮一秒,‘g’表示绿灯亮一秒。则字符串表示某个十字路口的交通信号灯闪烁依次为
假设当前交通信号灯显示的颜色为 ,问至少多少秒之内交通信号灯一定显示过绿色。
思路
遍历字符串,对每个显示颜色为 的位置暴力找到其下一个绿色信号多少秒后会出现,取最大值输出。
可以把字符串复制一遍放在其后,方便处理循环。
代码
#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
题目大意
给定一个正整数数组 。可以执行若干次下述操作:
- 选择任意数组下标 ,并用 替换 。
输出使数组中所有元素的乘积可以被 整除所需执行的最少操作数。无解输出 -1。
思路
令 表示 的质因数分解中有多少个 2。
则原问题变为从 中选择尽可能少的数使得被选择的数之和大于 。
代码
#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 个正整数 ,其中 和 。找出满足下列条件的任意一对数 和 :
- ,
- 。
保证 。
思路
范围比较小, 暴力尝试取 到 之间所有的值,看是否有合法的 。
代码
#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;
}