华为机试题

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

数组分割使最小值最大:二分最小值,同时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\n", 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 ? '\n' : ' ');
        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;
    }
};

 

posted @ 2020-04-23 12:14  Rogn  阅读(171)  评论(0编辑  收藏