Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Think about the final condition. “Impossible to seat anyone else” means every empty seat must be next to some occupied seat.
The existing 1s split the row into independent zero-blocks. Seats directly next to an existing 1 are already handled: they cannot be used, and they help stop extra placements.
So each maximal stretch of zeros only depends on whether it touches an existing 1 on its left and/or right. Handle those blocks separately and add the answers.
For a free path segment of length with no occupied neighbor helping from outside, the minimum number of chosen seats that makes it maximal is . One occupied seat can “kill” at most three positions: itself and its two neighbors.
For each zero block of length , remove one seat from for each side adjacent to an existing 1, because those boundary zeros are already blocked/dominated. Then add , where is the number of occupied neighbors around that block. Finally add the original number of 1s.
We need the minimum total number of occupied seats in a final valid state.
A final state is valid and “full” exactly when it is a maximal independent set on the path:
The existing 1s are fixed. So the job is not “place as many as possible”; it is the opposite: place as few extra students as possible while making every remaining 0 unplaceable.
Consider one maximal block of zeros. Suppose its length is .
There may be an existing 1 immediately to the left of the block, and/or immediately to the right. Each such neighboring 1 already handles one boundary zero:
1;So if the block has occupied neighbors around it, where , the part still needing new students has length
Now we need the minimum number of students to make a clean path segment of length maximal, with no outside help.
One newly occupied seat can cover at most three seats: itself, its left neighbor, and its right neighbor. Therefore at least
students are necessary.
This bound is also achievable: place students every three seats, for example at positions inside the segment, adjusting at the end if needed. Each chosen seat covers a block of up to three consecutive seats, and chosen seats are never adjacent. So the exact answer for that zero block is
In integer arithmetic:
Then the final answer is:
1s;1s from its length;This also handles the annoying edge cases cleanly:
0 gives , 1 gives ;1001: the middle block has , , so and no extra student is needed;The algorithm is a single scan over the string.
Complexity:
per test case, and
extra memory besides the input string. No drama, no DP hammer for a nail-sized problem.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
int ans = 0;
for (char c : s) ans += (c == '1');
int i = 0;
while (i < n) {
if (s[i] == '1') {
++i;
continue;
}
int l = i;
while (i < n && s[i] == '0') ++i;
int r = i - 1;
int len = r - l + 1;
int blocked = 0;
if (l > 0 && s[l - 1] == '1') ++blocked;
if (r + 1 < n && s[r + 1] == '1') ++blocked;
int freeLen = max(0, len - blocked);
ans += (freeLen + 2) / 3;
}
cout << ans << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
int ans = 0;
for (char c : s) ans += (c == '1');
int i = 0;
while (i < n) {
if (s[i] == '1') {
++i;
continue;
}
int l = i;
while (i < n && s[i] == '0') ++i;
int r = i - 1;
int len = r - l + 1;
int blocked = 0;
if (l > 0 && s[l - 1] == '1') ++blocked;
if (r + 1 < n && s[r + 1] == '1') ++blocked;
int freeLen = max(0, len - blocked);
ans += (freeLen + 2) / 3;
}
cout << ans << '\n';
}
return 0;
}