The final step is to output the sum of the minimum answers across rows, or $-1$ if any row is impossible. The runtime per test is $O(N^22^N)$.
#include <bits/stdc++.h>
using namespace std;
int solve() {
int N, A, B;
cin >> N >> A >> B;
vector<string> rows(N);
for (auto &row : rows) cin >> row;
assert(A == 1 && B == 0);
int ans = 0;
for (const auto &row : rows) {
int row_ans = INT_MAX;
for (int mask = 0; mask < (1 << N); ++mask) {
vector<bool> has_star(N);
bool ok = 1;
for (int c = 0; c < N; ++c)
if (mask & (1 << c)) has_star[c] = 1;
for (int c = 0; c < N; ++c) {
if (row[c] == 'W') {
ok &= !has_star[c];
} else if (row[c] == 'G') {
ok &= has_star[c] || (c && has_star[c - 1]);
} else {
ok &= c && has_star[c] && has_star[c - 1];
}
}
if (ok) {
row_ans =
min(row_ans, accumulate(begin(has_star), end(has_star), 0));
}
}
if (row_ans == INT_MAX) return -1;
ans += row_ans;
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) cout << solve() << "\n";
}
The first two steps are straightforward, while the last can be accomplished using a greedy approach. While there is an unsatisfied gray pixel, consider the leftmost such gray pixel - then we must choose to place a star in at least one of two locations (at the gray pixel, or to the left of it). It is always optimal to place a star at the gray pixel due to the following reasons:
This approach can be implemented with two left-to-right passes over each row of the input grid, the first for the black pixels and the second for the remaining pixels. The runtime per test is $O(N^2)$.
#include <bits/stdc++.h>
using namespace std;
int solve() {
int N, A, B;
cin >> N >> A >> B;
vector<string> rows(N);
for (auto &row : rows) cin >> row;
assert(A == 1 && B == 0);
int ans = 0;
for (const auto &row : rows) {
vector<bool> has_star(N);
for (int c = 0; c < N; ++c) {
if (row[c] == 'B') {
if (c == 0) return -1;
has_star[c - 1] = has_star[c] = true;
}
}
for (int c = 0; c < N; ++c) {
if (row[c] == 'W') {
if (has_star[c]) return -1;
} else if (row[c] == 'G') {
if (has_star[c]) continue;
if (c && has_star[c - 1]) continue;
has_star[c] = true;
}
}
ans += accumulate(begin(has_star), end(has_star), 0);
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) cout << solve() << "\n";
}
#include <bits/stdc++.h>
using namespace std;
int solve() {
int N, A, B;
cin >> N >> A >> B;
vector<string> rows(N);
for (auto &row : rows) cin >> row;
vector<vector<bool>> has_star(N, vector<bool>(N));
for (int r = 0; r < N; ++r)
for (int c = 0; c < N; ++c)
if (rows[r][c] == 'B') {
if (r - B < 0 || c - A < 0) return -1;
has_star[r][c] = has_star[r - B][c - A] = 1;
}
for (int r = 0; r < N; ++r)
for (int c = 0; c < N; ++c) {
if (rows[r][c] == 'W') {
if (has_star[r][c]) return -1;
} else if (rows[r][c] == 'G') {
if (has_star[r][c]) continue;
if (r >= B && c >= A && has_star[r - B][c - A]) continue;
has_star[r][c] = true;
}
}
int ans = 0;
for (const auto &row : has_star) ans += accumulate(begin(row), end(row), 0);
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) cout << solve() << "\n";
}
Brandon Wang's Python code:
CTI = {"W": 0, "G": 1, "B": 2}
def tc():
N, A, B = [int(x) for x in input().split()]
grid = [[CTI[x] for x in input()] for _ in range(N)]
stars = [[0 for _ in range(N)] for _ in range(N)]
for i in range(N):
for j in range(N):
if grid[i][j] == 2:
stars[i][j] = 1
if i < B or j < A:
print(-1)
return
if grid[i-B][j-A] == 0:
print(-1)
return
stars[i-B][j-A] = 1
for i in range(N):
for j in range(N):
if grid[i][j] == 1:
if stars[i][j] == 1:
continue
if i < B or j < A:
stars[i][j] = 1
continue
if stars[i-B][j-A] == 1:
continue
stars[i][j] = 1
print(sum(sum(x) for x in stars))
T = int(input())
while T > 0:
T -= 1
tc()