zoukankan      html  css  js  c++  java
  • 华为机试题

    共三题,第一题签到题,第二题字符串处理,不是很复杂的那种,第三题将数组分割使得最小值最大。

    数组分割使最小值最大:二分最小值,同时check是否有k组大于最小值。题目还要求有多个答案时,第一个分组尽可能地大,如果第一个分组也有多种情况,要使第二个分组尽可能地大,可以贪心处理,从后往前。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    int n, k;
    ll a[500+5];
    
    bool check(ll mid)
    {
        int cnt = 0;    // 当前划分数
        ll sum = 0;  // 当前和
        for(int i = 0;i < n;i++)
        {
            sum += a[i];
            if(sum >= mid)
            {
                cnt++;
                sum = 0;
                if(cnt >= k)  return true;
            }
        }
        return false;
    }
    
    int main()
    {
        cin >> n >> k;
        ll low = 0, high = 0, mid;
        for(int i = 0;i < n;i++)
        {
            cin >> a[i];
            high += a[i];
        }
    
        while(low <= high)
        {
            cout << low << " " << high << endl;
            mid = (low + high) >> 1;
            if(check(mid))  low = mid+1;
            else  high = mid-1;
        }
        mid += 2;
        while(!check(mid))  mid--;
        printf("mid: %lld
    ", mid);
    
        vector<int>res;   // 记录位置
        ll sum = 0;
        int cnt = 0;
        for(int i = n-1;i >= 0;i--)
        {
            sum += a[i];
            if(sum >= mid)
            {
                sum = 0;
                res.push_back(i);
                cnt++;
                if(cnt >= k-1)  break;
            }
        }
    
        for(int i = 0;i < n;i++)
        {
            printf("%lld%c", a[i], i == n-1 ? '
    ' : ' ');
            if(i+1 == res[res.size()-1])
            {
                printf("/ ");
                res.pop_back();
            }
        }
    
        return 0;
    }
    View Code

    发现leetcode上也有类似题,leetcode410,分割数组使最小值最大

    思路:二分最小值,check(检查如果最小值是mid,分组的个数)

    class Solution {
    public:
        bool check(vector<int>& nums, int m, long long mid)
        {
            int cnt = 1;
            long long sum = 0;
            for (int i = 0; i < (int)nums.size(); i++)
            {
                if (sum + nums[i] > mid)
                {
                    sum = nums[i];
                    cnt++;
                }
                else sum += nums[i];
            }
            return cnt <= m;
        }
        long long splitArray(vector<int>& nums, int m) {
            long long low = 0, high = 0, mid = 0;
            for (int num : nums)
            {
                low = max(low, (long long)num);
                high += num;
            }
            while (low < high)
            {
                //cout << low << " " << high << endl;
                mid = (low + high) >> 1;
                if (check(nums, m, mid))  high = mid;   // 保证high是ok的
                else  low = mid + 1;
            }
            //if (check(nums, m, mid - 1))  return mid - 1;
            //if (check(nums, m, mid))  return mid;
            return high;
        }
    };
  • 相关阅读:
    JS基础学习四:绑定事件
    常用JS事件对象
    jq 使用手册
    access数据库根据指定日期进行查询
    IP地址变动后,https://localhost:1158/em无法访问解决办法
    结构体对齐方式
    宏得到当前函数的名字
    std::list保存大量数据时,类型即是无析构函数,该list析构时会占用大量CPU
    装了vs2010 SP1后,开机速度慢
    查询SQL Server版本号
  • 原文地址:https://www.cnblogs.com/lfri/p/12759937.html
Copyright © 2011-2022 走看看