A. Marin and Photoshoot
题意:给你一串01字符串,可以选择在任意位置每次操作添加0或者1,最终使得字符串中每一个长度不小于2的子串中1的个数>=0的个数。求最少操作数。
思路:长度为3的连续子串中一定要至少有2个1,我们可以在遇到一个0的后面两个计算连续的1的个数,少几个添几个,详情看代码。
AC code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n;
string s;
void solve(){
cin>>n>>s;
int cnt=0;
int ans=0;
s='!'+s;
for(int i=1;i<=n;i++){
if(s[i]=='0'){
for(int j=i+1;j<=n;j++){
if(s[j]=='0'){
ans+=max(0,2-cnt);
cnt=0;
break;
}else{
cnt++;
}
}
}
}
cout<<ans<<endl;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
B. Marin and Anti-coprime Permutation
题意:一个排列是漂亮的当且仅当gcd(1*p1,2*p2,3*p3......,n*pn)>1,给你一个数n,求有多少个排列是漂亮的排列。
思路:下标为偶数,那么pi就可以放奇数,下标为偶数同理,因此n为奇数时满足条件的排列一定为0,n为偶数时就是n/2的阶层的平方,自己模拟一下其实就很容易发现。详情看代码
AC code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n;
const int mod=998244353;
void solve(){
cin>>n;
if(n&1){
cout<<0<<endl;
}else{
int t=n/2;
ll ans=1;
for(int i=t;i>=1;i--){
ans=(ans%mod*i%mod)%mod;
}
ans=(ans%mod*ans%mod)%mod;
cout<<ans<<endl;
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
C. Shinju and the Lost Permutation
题意:原始排列,会向右平移n次,最后一个数会移到首项,每次移动前的排列都有一个前缀最大值,给你一个数组c,c[i]表示第几次移动时,前缀最大值不同的有几个。问当前给出的数组c能否构造出满足条件的排列。
思路:c数组一定有1,且只有一次,每一次排列移动,如果是增加,一定只能增加1,即一个较小的数移动到首项了。如果是减少,不一定就减少1,可能是一个很大的数移动到首项。详情看代码。
AC code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10;
int n,c[N];
void solve(){
cin>>n;
int index=0;
for(int i=1;i<=n;i++){
cin>>c[i];
if(c[i]==1){
index=i;
}
}
if(count(c+1,c+n+1,1)!=1){
cout<<"NO"<<endl;
return ;
}
rotate(c+1,c+index,c+n+1);
for(int i=1;i<n;i++){
if(c[i+1]-c[i]>1){
cout<<"NO"<<endl;
return ;
}
}
cout<<"YES"<<endl;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}