牛客周赛53

A小红小紫投硬币

题意:小红有n+1枚硬币,小紫有n枚硬币,小红的硬币正面朝上的次数比小紫的硬币正面朝上的次数多的概率是多少

分析:一共有2^(n+1)×2^n次情况,有2^(n+1)×2(n-1)次小红的硬币正面朝上的次数比小紫的硬币正面朝上,所有概率为二分之一

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a;cin>>a;
    cout<<"0.500000"<<endl;
    return 0;
}

B小红的字符串

题意:给定一个字符串,判断至少需要几次操作才能变成回文字符串。每次操作可以把字母右移动,变成字母表的下一个字母,特别的,z变成a

分析:判断si变成sn-i-1需要操作几次,从左移到右直接相减,从右到左用26减去从左到右的次数即可。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    string s;cin>>s;
    ll len=s.size();
    ll sum=0;
    for(int i=0;i<len;i++){
        if(s[i]!=s[len-i-1]){
            if(s[i]-'a'<s[len-i-1]-'a'){
                ll c=s[len-i-1]-'a'+1-(s[i]-'a'+1);
                sum+=min(c,26-c);
            }
        }
    }
    cout<<sum<<endl;
}

C小红的01消除

题意:给定一个字符串,可以进行以下操作:

删除任意一个字串"11","01","00",小红最多能执行操作一x次,操作二y次,操作三z次。问小红最多可以执行多少次操作二。

分析:如果si后面包括本身0的个数小于等于1的个数,那么就可以操作1次,然后消除1个1。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int n;cin>>n;
    string s;cin>>s;
    int k1=0,k0=0;
    int c=0;
    int x,y,z;cin>>x>>y>>z;
    for(int i=n-1;i>=0;i--){
        if(s[i]=='1')k1++;
        if(s[i]=='0'){
            if(k1>0){
                k1--;
                c++;
            }
        }
        if(c==y)break;
    }
    cout<<c<<endl;
    return 0;
}

D小红组比赛

题意:有n场比赛,每场m道题,从每场选一道题,使其组成的难度分数最接近target,求最小值。

分析:dpij表示第i层有难度和为j,用背包存入难度共5000.每层的难度存好了,就可以给下一层

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m;cin>>n>>m;
    vector<vector<int>>a(n+10,vector<int>(m));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    int target;cin>>target;
    vector<vector<int>>dp(n+10,vector<int>(5010,0x3f3f3f3f));
    dp[1][0]=0;
    for(int i=1;i<=n+1;i++){
        for(int j=1;j<=m;j++){
            int dif=a[i][j];
            for(int s=5000;s>=dif;s--){
                if(dp[i][s-dif]!=0x3f3f3f3f){
                    dp[i+1][s]=min(dp[i+1][s],s-target);
                }
            }
        }
    }
    int ans=0x3f3f3f3f;
    for(int s=0;s<=5000;s++){
        if(dp[n+1][s]!=0x3f3f3f3f){
            ans=min(ans,abs(s-target));
        }
    }
    cout<<ans<<endl;
}

E折半丢弃

题意:给定一个数组,每次操作将任意一个数/2向下取整,使得没有出现在数组中的最小非负整数最大。求最大最小非负整数。

分析:用二分找那个最大的没有出现在数组中的最小非负整数,如果有比他更小的vis未被标记的,就将右区间缩小。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int t,n;
int a[N];
bool vis[N];
bool check(int x){
    memset(vis,0,sizeof vis);
    for(int i=1;i<=n;i++){
        int t=a[i];
        while(t&&(t>=x||vis[t]))t/=2;
        vis[t]=1;
    }
    for(int i=0;i<x;i++)
        if(!vis[i])return false;
    return true;
}
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        int l=1,r=n;
        while(l<r)
        {
            int mid=l+r+1>>1;
            if(check(mid))l=mid;
            else r=mid-1;
        }
        cout<<l<<endl;
    }
    return 0;
}

F小红走矩阵

题意:有个n×m的矩阵,小红位于起点(1,1),想到终点(n,m),每步可以往上下左右空地移动一格。小红可以进行最多一次操作:选择矩阵中的一处障碍替换成空地,代价是失去上下左右四个方向中一个移动的能力。求从起点到终点的最小步数。

分析:用bfs找出最小步数,枚举方向与当前禁止方向一直忽略,遇到墙,如果不能穿就忽略,如果能穿,就改成不能穿了。

代码:

#include<bits/stdc++.h>
using namespace std;
string a[1002];
bool vis[1001][1001][2][5];
int n,m;
int dx[]={1,0,0,-1},dy[]={0,1,-1,0};
struct node{
    int x,y,xuan,ban,dis;
};
queue<node> q;
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>a[i];
    q.push({0,0,1,4,0});
    q.push({0,0,0,3,0});
    q.push({0,0,0,2,0});
    q.push({0,0,0,1,0});
    q.push({0,0,0,0,0});
    vis[0][0][0][0]=1;
    vis[0][0][0][1]=1;
    vis[0][0][0][2]=1;
    vis[0][0][0][3]=1;
    vis[0][0][1][4]=1;
    
    while(!q.empty()){
        auto ck=q.front();
        q.pop();
        if(ck.x==n-1&&ck.y==m-1){
            cout<<ck.dis;
            return 0;
        }
        for(int i=0;i<4;i++){
            if(ck.ban==i) continue;
            int x=ck.x+dx[i],y=ck.y+dy[i];
            if(x<0||x>=n||y<0||y>=m) continue;
            if(vis[x][y][ck.xuan][ck.ban]) continue;
            if(a[x][y]=='X'&&ck.xuan==1) continue;
            if(a[x][y]=='X'){
                q.push({x,y,1,ck.ban,ck.dis+1});
                vis[x][y][1][ck.ban]=1;
            }
            else{
                q.push({x,y,ck.xuan,ck.ban,ck.dis+1});
                vis[x][y][ck.xuan][ck.ban]=1;
            }
        }
    }
    cout<<-1;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值