牛客周赛 Round 87【题解完成】

86 阅读3分钟
题目难度知识点
A 小苯的V图签到
B 小苯的数字切割签到
C 小苯的Z串匹配递推模拟
D 小苯的最大和★★DP
E 小苯的数组构造★★贪心,构造
F 小苯的ovo2.0★★暴力,贪心

image.png F题不会做,不过看题解有思路暴力写过了,还是太菜了。

小苯的V图

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,t;
int main(void)
{
    cin>>a[0]>>a[1]>>a[2];
    if(a[0]>a[1]&&a[1]<a[2]) puts("YES");
    else puts("NO");
    return 0;
}

小苯的数字切割

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,t;
int main(void)
{
    cin>>t;
    while(t--){
        string s; cin>>s;
        int ans=0;
        for(int i=0;i<s.size()-1;i++)
        {
            int sum1=0,sum2=0;
            for(int j=0;j<=i;j++) sum1=sum1*10+s[j]-'0';
            for(int j=i+1;j<s.size();j++) sum2=sum2*10+s[j]-'0';
            ans=max(ans,sum1+sum2);
        }
        cout<<ans<<'\n';
    }
    return 0;
}

小苯的Z串匹配

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,t;
char s[N];
int main(void)
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        int cnt=0;
        for(int i=0;i<n;i++) cin>>a[i];
        for(int i=0;i<n;i++) cin>>s[i];
        for(int i=0;i<n;i++){
            if(s[i]=='<' && a[i]>=0) a[i]=-1,cnt++;
            if(s[i]=='>' && a[i]<=0) a[i]=1,cnt++;
            if(s[i]=='Z' &&a[i]*a[i-1]<=0) a[i]=a[i-1],cnt++;
        }
        cout<<cnt<<'\n';
    }
    return 0;
}

小苯的最大和

image.png

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],f[N],n,t;
int main(void)
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        memset(f,-0x3f,sizeof f);
        f[0]=0;
        for(int i=1;i<=n;i++)
        {
            f[i]=max(f[i],f[i-1]+a[i]);
            if(i-2>=0) f[i]=max(f[i],f[i-2]);
            if(i-3>=0) f[i]=max(f[i],f[i-3]);
        }
        cout<<f[n]<<'\n';
    }
    return 0;
}

小苯的数组构造

image.png 贪心的构造,如果这里可以为1就尽可能的给1,需要注意的是必须给1就给不是必须就尽可能的不给。 因为需要构造的结果不能为0,所以尽可能的把1给需要的。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
int main(void)
{
    LL t; cin>>t;
    while(t--)
    {
        LL n,x,y; cin>>n>>x>>y;
        if(n==1)
        {
            if(x==y){
                puts("YES");
                cout<<x<<'\n';
            }else {
                puts("NO");
            }
            continue;
        }
        vector<LL>ve1(31,0),ve2(31,0),ans(31,0);
        for(LL i=0,j=x;i<31;i++,j/=2)
        {
            ve1[i]=j%2;
        }
        for(LL i=0,j=y;i<31;i++,j/=2)
        {
            ve2[i]=j%2;
        }
        int flag=1;
        for(int i=0;i<31;i++)
        {
            if(ve1[i]&&ve2[i]==0)
            {
                ans[i]=n/2*2;
            }
            if(ve1[i]&&ve2[i]) 
            {
                if(n&1) ans[i]=n;
                else ans[i]=n-1;
            }
            if(ve1[i]==0&&ve2[i]){
                flag=0;
            }
        }
        vector<int>ve;
        if(flag){
            for(int i=1;i<=n;i++)
            {
                LL sum=0;
                for(int j=0;j<31;j++)
                {
                    if(ans[j]&&ans[j]>=(n-i+1))
                    {
                        sum=sum+(1<<j),ans[j]--;
                    }
                }
                if(sum<=0)
                {
                    for(int j=0;j<31;j++)
                    {
                        if(ans[j])
                        {
                            sum=sum+(1<<j); ans[j]--;
                            break;
                        }
                    }
                }
                if(sum<=0) flag=0;
                ve.push_back(sum);
            }
        }
        if(flag) 
        {
            puts("YES");
            for(int i=0;i<n;i++) cout<<ve[i]<<" ";
            cout<<'\n';
        }
        else puts("NO");
    }
    return 0;
}

小苯的ovo2.0

image.png 贪心v都在中间o都在边上最优,故暴力枚举区间即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
typedef long long int LL;
LL pre[N],ne[N],t,n;
string s;
LL solve(int l,int r)
{
    string ss=s;
    for(int i=1;i<=n;i++)
    {
        if(ss[i]=='?'&&i>=l&&i<=r) ss[i]='v';
        if(ss[i]=='?'&&(i<l||i>r)) ss[i]='o';
    }
    LL sum=0;
    for(int i=0;i<=n+1;i++) pre[i]=0,ne[i]=0;
    for(int i=1;i<=n;i++)
    {
        pre[i]=pre[i-1];
        if(ss[i]=='o') pre[i]++;
    }
    for(int i=n;i>=1;i--)
    {
        ne[i]=ne[i+1];
        if(ss[i]=='o') ne[i]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(ss[i]=='v') sum+=pre[i-1]*ne[i+1];
    }
    return sum;
}
int main(void)
{
    cin>>t;
    while(t--)
    {
        cin>>s;
        n=s.size();
        s='0'+s;
        LL sum=0;
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++) {
                sum=max(sum,solve(i,j));
            }
        cout<<sum<<endl;
    }
    return 0;
}