Description
给定一个由 J
、O
、I
组成的字符串,求最多能拆分成多少 JOI
或 IOI
。
对于所有数据,\(1\leq \vert S\vert\leq 10^6\)。
Solution
先处理出 \(\text{pre}_i\) 为前缀 J
和 I
的数量,即能组成多少个头部。
然后倒着做,维护当前拼出的 I
、OI
和最终成品的数量。遇到 J
、O
就模拟拼接,遇到 I
判断当前的 \(\text{pre}_i\) 是否小于等于 I
、OI
的总数量,若成立就拼成 IOI
,否则作为 I
。
判断这个是因为 I
可以作为最后的 I
也可以作为开头的 I
。若大于等于前缀 J
、I
数量则作为最后的 I
数量够用,无需继续拼接了。
时间复杂度 \(\mathcal{O}(n)\)。
Code
#include <bits/stdc++.h>
using namespace std;
namespace Milkcat {
const int N = 2e7 + 5;
int n, ow, w, tot, pre[N]; char s[N];
int main() {
cin >> n >> (s + 1);
for (int i = 1; i <= n; i ++)
pre[i] = pre[i - 1] + (s[i] == 'J' || s[i] == 'I');
for (int i = n; i >= 1; i --) {
if (s[i] == 'J' && ow) ow --, tot ++;
if (s[i] == 'O' && w) w --, ow ++;
if (s[i] == 'I') {
if (ow + w >= pre[i] && ow) ow --, tot ++;
else w ++;
}
}
cout << tot << '\n';
return 0;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
while (T --) Milkcat::main();
return 0;
}
/*
15
NNOWWOONONWOWWO
*/
标签:pre,--,题解,JOIOI,++,int,ow,Tower
From: https://www.cnblogs.com/Milkcatqwq/p/17573017.html