Codeforces Round #829 (Div. 2)
A. Technical Support
题目大意:
判断每个问题(Q)是否被回答(A)。
根据题意判断即可,注意多个\(A\)可以对于一个\(Q\)。
\(code:\)
#include <bits/stdc++.h>
using namespace std;
inline void _main(){
int n;
string s;
cin>>n>>s;
int ans=0;
for(int i=0;i<s.size();++i){
if(s[i]=='Q'){
if(ans>=0) ans++;
else ans=1;
}
else{
ans--;
}
}
if(ans>0) puts("No");
else puts("Yes");
}
int main(){
int t;
cin>>t;
while(t--) _main();
return 0;
}
B. Kevin and Permutation
题目大意:
构造一个长度为\(n\)的排列,使其\(k = \min_{i=1}^{n-1}{|a_{i+1}-a_i|}\)最大。
不难发现(实在发现不了可以打表),\(k=\lfloor\frac{n}{2}\rfloor\),考虑构造一个满足条件的排列。
只需要保证相邻两项之差大于等于\(k\)即可。
\(code:\)
#include <bits/stdc++.h>
using namespace std;
inline void _main(){
int n;
static int vis[1000 + 5],a[1000 + 5];
cin>>n;
for(int i=1;i<=n;++i) vis[i]=0;
int k=n/2;
if(n%2==0){
int l=k,r=n;
for(int i=1;i<=k;++i) printf("%d %d ",l,r),l--,r--;
}
else{
for(int i=1;i<=n;i+=k) if(!vis[i]) printf("%d ",i),vis[i]=1;
for(int l=k;l>=2;--l)
for(int i=l;i<=n;i+=k) if(!vis[i]) printf("%d ",i),vis[i]=1;
}
printf("\n");
}
int main(){
int t;
cin>>t;
while(t--) _main();
return 0;
}
C1. Make Nonzero Sum (easy version)
题目大意:给出一个包含\(1,-1\)的序列,分成若干段,第\(i\)段\([l_i,r_i]\)的权值\(s_i\)为交替和\(a_{l_i} - a_{l_i+1} + a_{l_i+2} - a_{l_i+3} + \ldots \pm a_{r_i}\),使得\(s_i\)之和为\(0\),求划分方案。
不难发现,\(n\)为奇数无解。(因为对于一个区间长度\(len\),若\(len\)是偶数,则\(s_i\)取值也为偶,若\(len\)为奇数,则\(s_i\)取值也为奇,要使\(s_i\)之和等于\(0\),则必须有偶数个\(len\)为奇数)
题目对分成的段数没有要求,于是两项两项的考虑,若同号,则可以划分为一组,权值为\(0\),若异号,则分别划分成一组,两组权值和为\(0\)
\(code:\)
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 200000 + 5;
int n,a[MAX_N];
pair<int,int> ans[MAX_N];
inline void _main(){
int tot=0;
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
if(n&1){
puts("-1");
return;
}
for(int i=1;i<=n;i+=2){
if(a[i]*a[i+1]>0){
ans[++tot]=make_pair(i,i+1);
}
else{
ans[++tot]=make_pair(i,i);
ans[++tot]=make_pair(i+1,i+1);
}
}
sort(ans+1,ans+1+tot);
printf("%d\n",tot);
for(int i=1;i<=tot;++i) printf("%d %d\n",ans[i].first,ans[i].second);
}
int main(){
int t;
cin>>t;
while(t--) _main();
return 0;
}
C2. Make Nonzero Sum (hard version)
题目大意:给出一个包含\(1,0,-1\)的序列,分成若干段,第\(i\)段\([l_i,r_i]\)的权值\(s_i\)为交替和\(a_{l_i} - a_{l_i+1} + a_{l_i+2} - a_{l_i+3} + \ldots \pm a_{r_i}\),使得\(s_i\)之和为\(0\),求划分方案。
考虑在\(C1\)的方法上进行修改。
发现\(0\)对于题目只有更换正负号的作用。
于是,对于\(sum=\sum a_i\),我们考虑\(sum<0\)的情况:发现将一个\(+(-1)\)变成\(-(-1)\)会使得\(sum+=2\),\(sum>0\)同理。
所以\(sum\)为奇数的时候,无解。
然后再处理\(|sum|\)个\(+\)变\(-\)的情况即可。
\(code:\)
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 200000 + 5;
int n,a[MAX_N];
pair<int,int> ans[MAX_N];
inline void _main(){
int tot=0;
cin>>n;
int cnt=0;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n;++i) cnt+=(a[i]!=0);
if(cnt&1){
puts("-1");
return;
}
int sum=0;
for(int i=1;i<=n;++i) sum+=a[i];
if(sum>=0){
static bool vis[MAX_N];
for(int i=1;i<=n;++i) vis[i]=0;
for(int i=1;i<=n;++i){
if(a[i]==1 && sum>0){
if(i>1 && !vis[i-1]){
ans[++tot]=make_pair(i-1,i);
vis[i-1]=1,vis[i]=1;
sum-=2;
}
}
}
for(int i=1;i<=n;++i){
if(!vis[i]) ans[++tot]=make_pair(i,i);
}
sort(ans+1,ans+1+tot);
printf("%d\n",tot);
for(int i=1;i<=tot;++i) printf("%d %d\n",ans[i].first,ans[i].second);
}
else{
static bool vis[MAX_N];
for(int i=1;i<=n;++i) vis[i]=0;
for(int i=1;i<=n;++i){
if(a[i]==-1 && sum<0){
if(i>1 && !vis[i-1]){
ans[++tot]=make_pair(i-1,i);
vis[i-1]=1,vis[i]=1;
sum+=2;
}
}
}
for(int i=1;i<=n;++i){
if(!vis[i]) ans[++tot]=make_pair(i,i);
}
sort(ans+1,ans+1+tot);
printf("%d\n",tot);
for(int i=1;i<=tot;++i) printf("%d %d\n",ans[i].first,ans[i].second);
}
}
int main(){
int t;
cin>>t;
while(t--) _main();
return 0;
}
D. Factorial Divisibility
题面大意:给出一个长度为\(n\)的序列\(a_1,a_2,a_3,...,a_n\),求\(a_1!+a_2!+...+a_n!\)是否能被\(x!\)整除。
发现题目求的是\(\sum a_i!\),从\(a_{i-1}\)到\(a_i\)需要\(i\)个\(a_{i-1}\)相加,所以判断是否所有\(a_i\)能像\(2048\)那样变成\(a_n\)即可。
\(code:\)
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 500000 + 5;
int n,x,a[MAX_N],cnt[MAX_N];
int main(){
cin>>n>>x;
for(int i=1;i<=n;++i) cin>>a[i],cnt[a[i]]++;
for(int i=1;i<x;++i) while(cnt[i]>=(i+1)) cnt[i+1]++,cnt[i]-=(i+1);
bool flag=1;
for(int i=1;i<x;++i) if(cnt[i]) flag=false;
if(flag) puts("Yes");
else puts("No");
return 0;
}