牛客小白月赛牛客小白月赛115【题解待补】

91 阅读2分钟
题目难度知识点
A 过马路签到
B 签到题思维
C 命运之弹(Easy Version)思维
D 操作字符串★★gcd/贪心

image.png B题读假了,以为m个必须连续。D想到了循环节但是还是没思路看题解去了,发现挺简单的。

过马路

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

签到题

枚举签到题,看签到题的个数以及大于签到题的个数之和是否大于等于m,然后更新答案,注意最大为m。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
int a[N],s[N],n,m,ans;
int main(void)
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i],s[a[i]]++;
    for(int i=1;i<=n;i++) s[i]=s[i]+s[i-1];
    for(int i=1;i<=n;i++)
    {
        int temp1=s[a[i]]-s[a[i]-1];
        int temp2=s[n]-s[a[i]];
        if(temp1+temp2>=m) ans=max(ans,min(m,temp1));
    }
    cout<<ans;
    return 0;
}

命运之弹(Easy Version)

就是枚举在那次用,或者不用,当前用前面的次数+后面用了之后还需要的次数,所有的答案取一个min。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
int a[N],s[N],n,q,ans[N],b[N];
int main(void)
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    cin>>q;
    while(q--)
    {
        int x; cin>>x;
        for(int i=n;i>=1;i--)
        {
            b[a[i]]++;
            for(int j=0;j<=100;j++) s[j]=0;
            for(int j=1;j<=100;j++) s[j]=s[j-1]+b[j];
            ans[i]=s[100]-s[a[i]];
        }
        int cnt=0,flag=0;
        for(int i=1;i<=n;i++) if(a[i]>x) cnt++;
        for(int i=1;i<=n;i++)
        {
            if(a[i]<=x) continue;
            cnt=min(cnt,flag+ans[i]);
            flag++;
        }
        cout<<cnt<<'\n';
    }
    return 0;
}

操作字符串

image.png 就是求gcd,求最小的循环节,将所有的循环节对应位置的所有字符计一个数,求当前位置,那个字符出现的最多,那么最后都变成这个字母需要的最小次数累加。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*3+10;
string s[N];
int cnt[N][26],n,len,flag;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int main(void)
{
    cin>>n;
    for(int i=0;i<n;i++) cin>>s[i];
    len=gcd((int)s[0].size(),(int)s[1].size());
    for(int i=2;i<n;i++) len=gcd(len,(int)s[i].size());
    for(int i=0;i<n;i++)
    {
        int t=s[i].size();
        for(int j=0;j<t;j+=len)
        {
            string temp=s[i].substr(j,len);
            for(int z=0;z<temp.size();z++) cnt[z][temp[z]-'a']++;
            flag++;
        }
    }
    int ans=0;
    for(int i=0;i<len;i++)
    {
        int temp=0;
        for(int j=0;j<26;j++) temp=max(temp,cnt[i][j]);
        ans+=(flag-temp);
    }
    cout<<ans;
    return 0;
}