div4 题目
.Dashboard - Codeforces Round 898 (Div. 4) - Codeforces
1.Problem - G - Codeforces这一题我们首先进行分类讨论,因为情况很多
第一种情况当首尾存在一个B的情况时,我们可以吃掉所有的A,这个时候只需要计算出A的数量就可以
第二种情况是当首尾都是A,但是中间有连续的B的时候,这个时候我们也可以分别向左向右吃掉所有的A,次数为A的个数
第三种情况是首尾都是A,且中间没有连续的b,即只有一个单独B,这个时候要贪心选择A多的那一边吃完

1 signed main() { 2 cin >> _; 3 //_ = 1; 4 while (_--) { 5 string s; 6 cin >> s; 7 // cin >> n; 8 int n = s.length(), cnt = 0; 9 10 bool all = (s[0] == 'B' || s[n - 1] == 'B'); 11 12 for (int i = 0; i < n - 1; i++) { 13 if (s[i] == s[i + 1] && s[i] == 'B') all = true; 14 } 15 16 vector<int> lens; 17 int curr = 0; 18 for (int i = 0; i < n; i++) { 19 if (s[i] == 'A') 20 curr++; 21 else { 22 if (curr != 0) lens.push_back(curr); 23 curr = 0; 24 } 25 } 26 27 if (curr != 0) lens.push_back(curr); 28 sort(lens.begin(), lens.end()); 29 30 if (lens.empty()) { 31 cout << 0 << endl; 32 continue; 33 } 34 35 int tot = 0; 36 if (all) tot += lens[0]; //这种情况不存在连续B且两端没B 37 //此时我们只能选择A多的那一段贪心吃掉 38 for (int i = 1; i < lens.size(); i++) { 39 tot += lens[i]; 40 } 41 cout << tot << endl; 42 }
首先,要求区域内元素合,我们优先用前缀和预处理,然后要找到一个点可以整除的最大右端点,这个需要我们进行预处理,
然后再用二分去寻找答案,如果在范围内有合法答案,那我们就更新范围,否则继续缩小范围

1 bool check(int x) { 2 for (int i = 1; i <= n - x + 1; i++) { 3 if (a[i + x - 1] - a[i - 1] <= k && rmax[i] >= i + x - 1) 4 return 1; //合法情况 5 } 6 return 0; //没有合法情况 7 } 8 9 void solve() { 10 cin >> n >> k; 11 // cin >> s; 12 for (int i = 1; i <= n; i++) { 13 // cout << i << " "; 14 cin >> a[i]; 15 a[i] += a[i - 1]; 16 } 17 for (int i = 1; i <= n; i++) cin >> h[i]; 18 rmax[n] = n; 19 for (int i = n - 1; i >= 1; i--) { 20 if (h[i] % h[i + 1] == 0) 21 rmax[i] = rmax[i + 1]; //预处理最远到达合法右端点 22 else 23 rmax[i] = i; 24 } 25 int l = 0, r = n; 26 // int ans = 0; 27 while (l <= r) { 28 int mid = l + r >> 1; 29 30 if (check(mid)) { 31 l = mid + 1; 32 ans = mid; 33 } else { 34 r = mid - 1; 35 } 36 } 37 cout << ans << endl; 38 } 39 signed main() { 40 cin >> _; 41 while (_--) { 42 solve(); 43 }