C - Lock All Doors Editorial by en_translator
For each switching operation, if it locks a unlocked door, let us call it a locking operation; if it unlocks a locked door, call it an unlocking operation.
To minimize the number of switching operations, we may assume that an unlocking operation is never performed to a door to which an locking operation has been performed. This is true because, when we fix the set of doors to which we apply unlocking operations, we can always assume that we first apply unlocking operations too all those doors. Notably, we apply at most one locking and one unlocking operation to each door.
The number of locking operations is equal to the number of unlocking operations plus the number of initially open doors, so it is sufficient to consider the minimum possible number of unlocking operations.
We can make all doors locked if and only if, after performing all unlocking operations, the set of unlocked doors can be represented as \(\lbrace i \mid X \leq i \leq Y \rbrace (X \leq R, R - 1 \leq Y)\).
Therefore, denoting by \(x\) and \(y\) the minimum and maximum \(i\) with \(L_i = 0\), respectively, it is optimal to perform unlocking operations for all doors \(x, x + 1, \ldots, R - 1\) if \(x \leq R - 1\), and also for all doors \(R, R + 1, \ldots, y\) if \(y \geq R\).
Sample code
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, r;
cin >> n >> r;
vector<int> l(n);
for (int i = 0; i < n; i++) cin >> l[i];
int x = n, y = 0;
for (int i = 0; i < n; i++) {
if (l[i] == 0) {
x = i;
break;
}
}
for (int i = n - 1; i >= 0; i--) {
if (l[i] == 0) {
y = i;
break;
}
}
int open = count(l.begin(), l.end(), 0);
int t = 0;
if (x <= r - 1) for (int i = x + 1; i < r; i++) if (l[i] == 1) t++;
if (y >= r) for (int i = r; i < y; i++) if (l[i] == 1) t++;
int ans = 2 * t + open;
cout << ans << '\n';
}
posted:
last update: