A题
暴力就可以
void solve(){
cin>>s;
for(int i=1;i<s.size();i++){
if(s[i]!=s[i-1]) sum++;
}
cout<<sum;
}
B题
数学题,找到每一段符合条件的子串,然后这一条符合条件的子串有(1+len(s)-1)/2符合条件,注意的就是处理最后一段,就好了。
void solve(){
cin>>s;
ll j=0;
ll i=1;
for(i=1;i<s.size();i++){
if(s[i]==s[i-1]&&i-j+1>=2){
sum+=(1+i-j-1)*(i-j-1)/2;
j=i;
}
}
if(i-j+1>=2) sum+=(i-j)*(i-j-1)/2;
cout<<sum;
}
C题
如果k是奇数的话就可以构造成1111101010000000,旁边是多余的01,中间是k对不相同相邻的字符串。如果是偶数,就构造成1111101010000001,与奇数不同的就是把后面的多余的01,放到n-1的位置(把这一段k看成整体),然后就是构造不出的
void solve(){
ll a,b,k;
cin>>a>>b>>k;
string s="";
if((a!=b&&min(a,b)*2<k)||(a==b&&a*2-1<k)||(k==0&&a+b!=max(a,b))){
cout<<"-1\n";
return;
}
int sa=0,sb=1;
if(a>b) swap(a,b),swap(sa,sb);
if(k%2==1){
for(int i=0;i<=b-(k+1)/2;i++){
s+=('0'+sb);
}
for(int i=0;i<k;i++){
if(i%2) s+='0'+sb;
else s+='0'+sa,a--;
}
while(a--) s+='0'+sa;
}
else{
for(int i=0;i<=b-k/2-1;i++){
s+='0'+sb;
}
b-=b-(k+1)/2;
for(int i=0;i<k-1;i++){
if(i%2) s+='0'+sb,b--;
else s+='0'+sa,a--;
}
while(a--) s+='0'+sa;
if(b) s+='0'+sb;
}
cout<<s<<'\n';
}
D题
先预处理出当前位置的下一个相同的位置在哪里,下一个不相同的位置在哪里,然后就很简单的dp一下就可以了。
//a[i]当前位置下一个相同的,b[i]当前位置下一个不相同的
void solve(){
cin>>n>>x>>y;
cin>>s;
s=' '+s;
int t0=-1,t1=-1;
for(int i=n;i>=1;i--){
if(s[i]=='0'){
a[i]=t0;
b[i]=t1;
t0=i;
}
else{
a[i]=t1;
b[i]=t0;
t1=i;
}
dp[i]=1e18;
}
dp[0]=dp[1]=0;
for(int i=1;i<=n;i++){
if(a[i]!=-1) dp[a[i]]=min(dp[i]+x,dp[a[i]]);
if(b[i]!=-1) dp[b[i]]=min(dp[b[i]],dp[i]+y);
}
cout<<dp[n];
}