牛客刷题·组队竞赛·进制转换·连续最大和

在这里插入图片描述
第一题
组队竞赛
在这里插入图片描述
这道题目要注意的点是队伍的平均水平等于该队伍第二高水平,所以我们只需要让分出的几个队伍里第二高更大一点即可。
在这里插入图片描述
这道题我们只需要选择尽量打的两个数。可以借助排序来完成。
在这里插入图片描述
现在我们来观察取数的规律。来一个数据量更大的例子
在这里插入图片描述
一共有三组,第一组中间值下标为7,第二组下标为5,可以发现是依次减2的。有几组就循环几次。
加下来就可以根据逻辑写代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int num = 0;
    int ret = 0;//记录返回值
    cin >> num;
    vector<int> score(3*num);
    for (int i = 0; i < 3 * num; i++)
    {
        cin >> score[i];
    }
    sort(score.begin(), score.end());
    for (int i = 0; i < num; i++)
    {
        ret += score[score.size() - 2 * (1 + i)];
    }
    cout << ret;
    return 0;
}

在这里插入图片描述
提交后发现有报错,这是因为我们定义的ret为int类型的,然而数据太大超出了int能表示的范围。
我们需要将int改为long就可以,再提交一遍。
在这里插入图片描述
第二题,进制转换
在这里插入图片描述
如果n大于9,对应数字参考16进制。
借助十进制来描述
在这里插入图片描述
在十进制以内我们还是可以轻松解决的,但是后边字母表示如何来实现呢?
我们可以借助一个字符数组
在这里插入图片描述
那二进制举一个例子
在这里插入图片描述
模拟上边的过程即可求出答案

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    int m, n;
    cin >> m >> n;
    string s = "0123456789ABCDEF";
    string ret;
    while (m !=0)
    {
        ret=ret+s[m%n];
        m  /= n;
    }
    reverse(ret.begin(), ret.end());
    cout << ret;
    return 0;
}

运行后发现只会通过部分用例
在这里插入图片描述

这是因为我们忽略了0和负数的情况
所以我们要优化代码

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    int m, n;
    int flag=0;
    cin >> m >> n;
    if(m==0)
    {
        cout<<0;
        return 0;
    }
    else if(m<0)
    {
        m=0-m;
        flag=1;
    }
    string s = "0123456789ABCDEF";
    string ret;
    while (m)
    {
        ret=ret+s[m%n];
        m  /= n;
    }
    if(flag==1)
    {
        ret+='-';
    }
    reverse(ret.begin(), ret.end());
    cout<<ret;
    return 0;
}

第三题
连续最大和

在这里插入图片描述
这道题要我们求出最大的连续子串的和,是因为数组中含有负数。
如何找到子数组的最大和呢?
我们可以来模拟一下
在这里插入图片描述
我们可以模拟上边的过程
在这里插入图片描述
在第一次时,max的值初始化为5,定义一个sum。sum一直向后遍历,当sum为负数且遇到一个正数时,就将sum变换为当前遍历的值。
在这里插入图片描述
已经分析的很清晰了,接下来是代码呈现。

#include <iostream>
#include <vector>
using namespace std;
int getMax(int a, int b){    
    return a>b? a:b; 
}

int main(){    
    int num;
    cin >> num;
    vector<int> arr;
    arr.resize(num);
    
    for(int i=0; i<num; ++i){
        cin >> arr[i];
    }    
    int sum = arr[0];
    int maxSum = arr[0];
    for(int i=1; i<num; ++i){
        sum = getMax(arr[i], sum+arr[i]);
        if(sum > maxSum){
           maxSum = sum;
        }
    }
    cout << maxSum;
    return 0;
}

这道题的状态方程式为
在这里插入图片描述
可以看出这里类似于一个动态规划的问题,dp[i]就是以i结尾的子数组的和。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

we will rise.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值