NC53185. JOIOI 塔
描述
输入描述
第一行为一个整数$N$,表示字符串$S$的长度。第二行是一个字符串$S$。
输出描述
输出一行一个整数:表示能够做出的迷你JOIOI塔数量的最大值。
示例1
输入:
6 JOIIOI
输出:
2
说明:
JOIIOI分别含子串JOI和子串IOI各一个,故可以做出2个迷你JOIOI塔。示例2
输入:
5 JOIOI
输出:
1
说明:
虽然JOIOI也分别含子串JOI和子串IOI各一个,但每个字符不能被使用两次或以上。示例3
输入:
6 JOIOII
输出:
2
说明:
此样例对应题目描述中的例子。示例4
输入:
15 JJOIIOOJOJIOIIO
输出:
4
C++(clang++ 11.0.1) 解法, 执行用时: 148ms, 内存消耗: 1384K, 提交时间: 2022-08-08 17:23:48
#include <bits/stdc++.h> using namespace std; int l = 0, r, ans = 0, n; char s[1000005]; bool check(int x) { int ans = 0, tot = 0, cnt = 0; for (int i = n; i; i--) { if (x == ans) return 1; if (s[i] == 'J') { if (tot) tot--, ++ans; continue; } if (s[i] == 'O') { if (cnt) --cnt, ++tot; continue; } if (s[i] == 'I') { if (ans + tot + cnt < x) cnt++; else { if (tot) tot--, ans++; } } } if (x == ans) { return 1; } return 0; } int main() { scanf("%d%s", &n, s + 1); r = n; while (l <= r) { int mid = (l + r) >> 1; if (check(mid)) ans = mid, l = mid + 1; else r = mid - 1; } printf("%d", ans); }