共三題,第一題簽到題,第二題字符串處理,不是很復雜的那種,第三題將數組分割使得最小值最大。
數組分割使最小值最大:二分最小值,同時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; }
發現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; } };