牛客练习赛61题解ABC

A-打怪

传送门:https://ac.nowcoder.com/acm/contest/5026/A

图片说明
思路:首先可以自己先去模拟一下样例是怎样实现的,熟悉一下思路。然后,我们可以看到,我是先手,只有当我的血量为0的时候,游戏才结束。在看到题目给出的数据又不是很大,所以可以模拟出双方每次的血量变化量,然后一边记下少了几个怪即可。但是这里我们要到单独考虑哪些情况下是-1.显然,如果毛怪一下都打不到你的话,你的血量就一直不变,如果在杀死每个毛球怪的循环中,你会被毛怪攻击到,那么肯定有这么一个回合,你的血量会为0。想清楚了这点,就可以写出代码了。

代码+详细注释

#include<bits/stdc++.h>
using namespace std;
void solve(){
    int pb,pa,gb,ga;  //pb表示人的血量,pa表示人的攻击力,gb表示怪的血量,pa表示怪的攻击力
    int ans=0;
    cin>>pb>>pa>>gb>>ga;
    if(gb<=pa)  cout<<"-1"<<endl;  //如果怪连人的第一个回合都扛不住的话,那么说明人就得了永生
    else{  //否则
        int temp=gb;  //先将怪的初始血量存下
        while(pb>0){  //在人的血量大于0的情况下
            gb-=pa;  //怪的血量先减
            if(gb<=0){  //怪被打死的情况
                ans++;  
                gb=temp;  //恢复成下一个怪的初始血量
            }
            else  pb-=ga;  //如果怪没被打死的话,说明它可以攻击人
        }
        cout<<ans<<endl;
    }
}
int main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

B 吃水果

传送门:https://ac.nowcoder.com/acm/contest/5026/B

图片说明
思路:贪心+模拟,首先,你还是可以先进行一些模拟,寻找到一些规律来。然后,为了方便,我们先进行一些处理让n是m和n当中更小的那个。如果,m==n的话,那么直接输出答案即可,否则,n就是更小的那个,m就是更大的那个。我们可以看到,这个数据范围还是比较小,因此可以用第一题的思路,依然用循环,模拟出每一步的情况,在进行处理即可。
我们可以看到,在n,m都不为0的情况下,如果,m大于n的两倍的话,例如n=2,m=7,那么最好的办法就是将n进行翻倍,如果m在n的1-2倍之间的话,那么此时的最优解就是吃一个苹果和香蕉。如果n==m的话,那么可以直接得到当前的ans+n就是最终答案了

代码+详细注释

#include<bits/stdc++.h>
using namespace std;
void solve(){
    int n,m;
    cin>>n>>m;
    int ans=0;
    if(n>m)  swap(n,m);  //认为规定n要小于m
    if(n==m)  cout<<n<<endl;
    else{
        while(n!=0&&m!=0){
            while(n*2<=m){  //如果m超过了n的2倍
                ans++;
                n*=2;  //n翻倍
            }
            if(n==m){  //n==m的话,ans+n跳出
                ans+=n;
                n=m=0;
            }
            else if(m/n==1){  //如果,m在n的1-2倍之间
                n--,m--;  //同时-1
                ans++;
            }
        }
        cout<<ans<<endl;
    }
}
int main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

C题 四个选项

传送门:https://ac.nowcoder.com/acm/contest/5026/C

图片说明
思路:并查集+dfs,在做这题的时候,想得到是dfs,但是就是还没有接触到并查集,所以卡在了如何进行分组的地方了。事后赶紧补上。还是那样,可以看到,这题的数据还是不算大,因此可以现根据条件进行一些分组,显然是将选项一样的分为同一组,确保哪几个题的选项要是一致的。
首先,我对输入的数据进行处理,根据限制条件进行适当的分组,这里用的就是并查集用法,当然,这里不用路径压缩也行。复杂度完全是够的。并查集的知识点就不再这里做展开了,可以自行bing。我们重点来介绍一下用dfs怎样进行实现的。首先,我们将有5个参数为l,a,b,c,d,l表示的是你一共确定了几道题的选项,后面4个参数分别是当前的a,b,c,d四个选项的个数有多少

void dfs(int l,int a,int b,int c,int d){
    if(l==12){  //递归结束的条件
        int i;
        if(na!=a||nb!=b||nc!=c||nd!=d)  return;  //如果这种情况下的a,b,c,d的个数不符合题目的要求,直接退出
        //接下来就是对那些m个限制条件进行处理了
        for(i=1;i<=12;i++){  //检查一下每一题的选项
            if(t[i]!=t[v[i]])   break;  //如果这种情况的分配下,其中某两题的选项不一样,但是题目的要求有要是一样,说明这种情况不符合。
        }
        if(i<=12)  return;  //不符合的情况
        ans++;  //既满足大条件,又满足限制的条件,哪这种情况就可以
        return;
    }
    //每个题目有下面4个选项可以选择,分别查找即可
    t[l+1]=1,dfs(l+1,a+1,b,c,d); //以此为当前的题目选a,b,c,d对应1,2,3,4,其中t[i]表示第i个题目的选项是1,2,3,4中的哪一个
    t[l+1]=2,dfs(l+1,a,b+1,c,d);
    t[l+1]=3,dfs(l+1,a,b,c+1,d);
    t[l+1]=4,dfs(l+1,a,b,c,d+1);
}

代码+详细注释

#include<bits/stdc++.h>
using namespace std;
int na,nb,nc,nd,m,ans;
int v[20],t[20];
int find(int x){  //并查集查找根节点
    if(x==v[x])  return x;
    return v[x]=find(v[x]);
}
void dfs(int l,int a,int b,int c,int d){
    if(l==12){  //递归结束的条件
        int i;
        if(na!=a||nb!=b||nc!=c||nd!=d)  return;  //如果这种情况下的a,b,c,d的个数不符合题目的要求,直接退出
        //接下来就是对那些m个限制条件进行处理了
        for(i=1;i<=12;i++){  //检查一下每一题的选项
            if(t[i]!=t[v[i]])   break;  //如果这个选项不属于
        }
        if(i<=12)  return;
        ans++;
        return;
    }
    //每个题目有下面4个选项可以选择,分别查找即可
    t[l+1]=1,dfs(l+1,a+1,b,c,d); //以此为当前的题目选a,b,c,d
    t[l+1]=2,dfs(l+1,a,b+1,c,d);
    t[l+1]=3,dfs(l+1,a,b,c+1,d);
    t[l+1]=4,dfs(l+1,a,b,c,d+1);
}
int main(){
    cin>>na>>nb>>nc>>nd>>m;
    for(int i=1;i<=12;i++)  v[i]=i;  //先将每个数据的根节点设为自己
    int i,j,x,y;
    while(m--){
        cin>>x>>y;
        i=find(x),j=find(y);  //查找根节点来确定他们是否为同一组的
        if(i!=j)  v[i]=j;
        //如果x,y的根节点不一样的话,但是题目要求的又是他们选项要一致,
        //所以可以将其中一个的根节点设为另一个的根节点
    }
    dfs(0,0,0,0,0);
    cout<<ans<<endl;
    return 0;
}
全部评论

相关推荐

01-11 08:47
门头沟学院 Java
程序员花海_:所以看起来还是实习的好处多 给导师打黑工能学到什么
点赞 评论 收藏
分享
1.第一种人呢以92和计算机强双非(四邮四电)偏多,这种人呢,喜欢把自己的学校称为“大专”,极力在交流时贬低自己的学历,放大自己学历的缺点(如牛客经典贴,双非秋招oc美团,点开发现是985硕士🤣🤣🤣),说的自己学校好像比双非认可度还低,好像这样才能突出自己多么牛逼,克服了多少困难,技术有多强,但你要是说想双非考研去他们学校,他们又要狠狠打压你,告诉考他们学校多难了🤣🤣🤣。从92到大厂明明是证明自己一直优秀的一条路,你不走,你非要故意恶心自己也恶心别人,何必呢?2.第二种人以像我一样的双非同学偏多,大多学历比较低,可能又带有中大厂实习。他们会在你交流的时候,十分刻意的强调自己是弱双非或者学院本,再不经意透露自己在某某大厂实习。等着群聊里响起“原来是xx(大厂名字)✌🏻啊,给你跪了😭”,他们便心满意足了。不用反驳,因为我之前也是这种人,现在也有这种倾向😆😆😆。3.第三种人更是神人,跟这种人交流时,你会觉得对方已经被美国植入芯片控制了,张嘴闭嘴只有膜膜膜,羡慕羡慕羡慕。上到拿到大厂offer,下到喝一杯奶茶,他们都说羡慕。不知道他们的生活过得有多么悲惨,连喝杯饮料都到了羡慕的地步🤣🤣🤣。天天就是在群里面互相吹捧,互相羡慕,不知道交流起来有什么意思。4.第四种人则是第一种人的对立面,我有时候觉得是第四种人太多才会导致第一种人的出现。这种人天生带着对92的恨。仿佛学计算机没有拿到offer全是92导致的。他们是小说里被陷害的白莲花女主,92则是夺走他们人生的恶毒女配。在他们的眼中,他们的技术要比92好一百倍,但是所有企业都识别不了他们这匹千里马。实际自己从来没想过,在ai与辅导课程普及的当日,所谓的计算机,早已经没有了任何的技术壁垒,否则也不会有那么人转码了😂。这是那天回家路上发抖音的,讨论不少,有赞同有不赞同的,其实有时候也在想自己言论是否偏激。今天遇到朋友问我好久没更新牛客了,就搬了上去。其实很简单,加了交流群之后,发现交流的质量参差不齐,有些实在言之无物,想了想自己也会有这样的问题。自己也在建交流群,希望能避免这样的现象吧
wu970:交流群不就是一群人互相装逼和加装谦虚吗
如何排解工作中的焦虑
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务