比赛地址:https://ac.nowcoder.com/acm/contest/11170#question
A:
分以下 3 种情况:
1、如果存在长度为 1 的极长全 1 子串,那么将这个子串反转,变为 0 ,答案减少 1 ,例如 100110011
2、如果存在一个 0 ,在两个全 1 子串中间,则把这个 0 反转变成 1 ,答案减少 1 ,例如 11101100
3、以上情况都没有,用O(n)复杂度算出权重,即答案
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
int ans=0,f=0;
for(int i=0;i<s.size();)
{
int j,chang=0;
for(j=i;j<s.size();j++)
{
if(s[j]=='0') break;
chang++;
}
if(chang==1)
{
f=1;
}
if(chang!=0) ans++;
i=j+1;
}
for(int i=1;i<s.size()-1;i++)
{
if(s[i]=='0'&&s[i-1]=='1'&&s[i+1]=='1') f=1;
}
if(f==1) cout<<ans-1<<endl;
else cout<<ans<<endl;
return 0;
} B:
为了方便,以下题解及程序的数组下标从1开始(题目从0开始),用j表示a[j],k表示b[k],ansa表示a数组所有元素之和,ansb表示b数组所有元素之和。
我们分以下4种情况来分类讨论:
i = 1:j 和 k 必须 ≥ 2,则
i = 2:j 和 k 必须有一个 = 1,另外一个 ≥ 3,或者两个都是 1 ,则
i = 3:j 和 k 一个 = 1,一个 = 2,则
i ≥ 4:不可能有 j 和 k 满足条件,则
以上公式均没有加入取模运算,详情见代码
#include<bits/stdc++.h>
using namespace std;
const long long modd=998244353;
const int maxn=1e5+10;
long long a[maxn],b[maxn];
int main()
{
int n;
scanf("%d",&n);
long long ansa=0,ansb=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
ansa+=a[i];
ansa%=modd;
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&b[i]);
ansb+=b[i];
ansb%=modd;
}
long long ans1,ans2;
ans1=ansa-a[1],ans2=ansb-b[1];
if(ans1<0) ans1+=modd;
if(ans2<0) ans2+=modd;
cout<<(ans1*ans2)%modd<<" ";
ans1=ansa-a[2],ans2=ansb-b[2];
if(ans1<0) ans1+=modd;
if(ans2<0) ans2+=modd;
ans1-=a[1],ans2-=b[1];
if(ans1<0) ans1+=modd;
if(ans2<0) ans2+=modd;
cout<<(((ans1*b[1])%modd+(ans2*a[1])%modd)%modd+(a[1]*b[1])%modd)%modd<<" ";
cout<<((a[1]*b[2])%modd+(b[1]*a[2])%modd)%modd<<" ";
for(int i=4;i<=n;i++)
{
printf("0 ");
}
printf("\n");
return 0;
}
京公网安备 11010502036488号