牛客小白月赛86 A-E题解

A.水盐平衡

        数学。签到题,可以直接计算浓度并进行比较,也可以转化为a*d与b*c的比较。

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+5;
int a[N];
void solve(){
	int a,b,c,d;cin>>a>>b>>c>>d;
    if((a*d)>(b*c)){
        cout<<"S"<<endl;
    }
    else{
        cout<<"Y"<<endl;
    }
}

signed main(){
	ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
	int t=1;
	cin>>t;
	while(t--) solve();
	return 0;
}

B.水平考试

        模拟。读入字符串后,首先特判字符串,若S比F的长度长,不用想肯定为0分。注意本题题意说明只可多不可少,因此不可能出现得5分的情况。故只需要判断A、B、C、D在两个字符串中出现的次数即可。(记得初始化!赛时因为这个wa了3发ToT)

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+5;
int n1[4],n2[4];
void solve(){
	string S;cin>>S;
    string F;cin>>F;
    int ans=0;
    if(S.size()>F.size()){
        cout<<"0"<<endl;
        return;
    }
    for(int i=0;i<S.size();i++){
        n1[S[i]-'A']++;
    }
    for(int i=0;i<F.size();i++){
        n2[F[i]-'A']++;
    }
    for(int i=0;i<4;i++){
        if(n1[i]==1&&n2[i]==0){
            cout<<"0"<<endl;
            return;
        }
    }
    cout<<"10"<<endl;
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
	int t=1;
	cin>>t;
	while(t--) solve();
	return 0;
}

C.数组段数

        前缀和。题意相当简单,朴素做法即在询问区间中元素相同(题意中即数字相同)的子串分为一段即可。为了防止TLE,用前缀和处理一遍即可。处理思路:用b数组记录原数组总共可以分为几段。注意到相同元素会分为同一段,可以得出:当前元素与前一个元素相同时,则这两个元素划分在同一段。

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+5;
int a[N],b[N];
void solve(){
	int n,m;cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    b[1]=1;
    for(int i=2;i<=n;i++){
        if(a[i-1]==a[i]) b[i]=b[i-1];
        else{
            b[i]=b[i-1]+1;
        }
    }
    while(m--){
        int l,r;cin>>l>>r;
        if(l==r){
            cout<<"1"<<endl;
            continue;
        }
        cout<<b[r]-b[l]+1<<endl;
    }
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
	int t=1;
	//cin>>t;
	while(t--) solve();
	return 0;
}

D.剪纸游戏

        DFS(深度优先搜索)。这题实现过程不难,主要是判断是否为矩形有一定难度。可以发现,若剪出来的区域为矩形,此时数出来的“.”的数量与该区域的横坐标覆盖区间与纵坐标覆盖区间之积相同。而为了数出“.”的数量则采用DFS。

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1010;
char a[1010][1010];
int n,m;
int cnt;
int mxx,mxy,mnx,mny;

int dx[4]={0,-1,0,1},dy[4]={1,0,-1,0};

void dfs(int x,int y){
    a[x][y]='*';
    cnt++;
    mxx=max(mxx,x);
    mnx=min(mnx,x);
    mxy=max(mxy,y);
    mny=min(mny,y);
    for(int i=0;i<4;i++){
        int tx=x+dx[i];
        int ty=y+dy[i];
        if(tx>=0&&ty>=0&&tx<n&&ty<m&&a[tx][ty]=='.'){
            dfs(tx,ty);
        }
    }
}

void solve(){
	cin>>n>>m;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    
    int ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]=='.'){
                mxx=0;mnx=n;mxy=0;mny=m;
                cnt=0;
                dfs(i,j);
                if(cnt==(mxx-mnx+1)*(mxy-mny+1)) ans++;
            }
        }
    }
    cout<<ans<<endl;
}

signed main(){
	ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
	int t=1;
	//cin>>t;
	while(t--) solve();
	return 0;
}

E.可口蛋糕

        思维,前缀和,双指针。参考了榜一大佬的代码,该题主要难点在于如何优化时间复杂度,可以用前缀和预处理。处理思路:将饱腹度与可口度都求前缀和,接着用双指针去寻找最大合法区间(即满足饱腹度的区间值),再找出合法区间的可口度最大值即可。该题思维难度较高。

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e6+5;
int a[N],b[N];
void solve(){
	int n,m;cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i]+=a[i-1];
    }
    for(int i=1;i<=n;i++){
        cin>>b[i];
        b[i]+=b[i-1];
    }
    
    int j=0,res=1e18,ans=-1e18;
    for(int i=1;i<=n;i++){
        while(a[i]-a[j]>=m){
            res=min(res,b[j]);
            j++;
        }
        ans=max(ans,b[i]-res);
    }
    cout<<ans<<endl;
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0), cout.tie(0);
	int t=1;
	//cin>>t;
	while(t--) solve();
	return 0;
}

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值