This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "paint.h"
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <bits/stdc++.h>
using namespace std;
std::string solve_puzzle(std::string s, std::vector<int> c) {
int k = c.size();
int n = s.size();
int ps[2][n]; // X _
ps[0][0] = (s[0] == 'X');
ps[1][0] = (s[0] == '_');
for(int i=1; i<n; i++) {
ps[0][i] = ps[0][i-1] + (s[i] == 'X');
ps[1][i] = ps[1][i-1] + (s[i] == '_');
}
int can[2][n]; // X _
for(int i=0; i<2; i++) {
for(int j=0; j<n; j++) {
can[i][j] = 0;
}
}
int mx[n];
int prv = 0;
for(int i=0; i<n; i++) {
if(s[i] == 'X') prv = i;
mx[i] = prv;
}
int mx2[n];
prv = n-1;
for(int i=n-1; i>=0; i--) {
if(s[i] == 'X') prv = i;
mx2[i] = prv;
}
if(k == 1) {
int ok[n] = {};
for(int i=c[0]-1; i<n; i++) {
if(ps[1][i] - (i == c[0] - 1 ? 0 : ps[1][i - c[0]]) == 0) {
if(i == c[0] - 1 || ps[0][i - c[0]] == 0) {
if(ps[0][n-1] - ps[0][i] == 0) {
ok[i] = 1;
}
}
}
}
for(int i=1; i<n; i++) ok[i] += ok[i-1];
for(int i=0; i<n; i++) {
can[0][i] = ok[min(n-1, i + c[0] - 1)] - (i > 0 ? ok[i-1] : 0);
can[1][i] = (i > 0 && ok[i-1] > 0 && ps[0][n-1] - ps[0][i] == 0) || (i + c[0] < n && ok[n-1] - ok[i + c[0] - 1] > 0 && ps[0][i-1] == 0);
}
}
else {
bool dp_forward[k][n];
bool dp_backward[k][n];
for(int i=0; i<k; i++) {
for(int j=0; j<n; j++) {
dp_forward[i][j] = dp_backward[i][j] = 0;
}
}
int dp_forsum[k][n];
int dp_backsum[k][n];
for(int i=0; i<k; i++) {
for(int j=0; j<n; j++) {
dp_forsum[i][j] = dp_backsum[i][j] = 0;
}
}
int real_dp[k][n]; // The real answer to question "i-th black segment ENDING at j-th column?"
int real_sum[k][n];
for(int i=0; i<k; i++) {
for(int j=0; j<n; j++) {
real_dp[i][j] = 0;
real_sum[i][j] = 0;
}
}
for(int i=c[0]-1; i<n; i++) {
if(ps[1][i] - (i == c[0] - 1 ? 0 : ps[1][i - c[0]]) == 0) {
if(i == c[0] - 1 || ps[0][i - c[0]] == 0) {
dp_forward[0][i] = 1;
}
}
dp_forsum[0][i] = (i == 0 ? 0 : dp_forsum[0][i-1]) + dp_forward[0][i];
}
int cum = c[0] + 1;
for(int i=1; i<k; i++) {
cum += c[i];
for(int j=cum-1; j<n; j++) {
if(ps[1][j] - ps[1][j-c[i]] > 0) {
dp_forsum[i][j] = dp_forsum[i][j-1] + dp_forward[i][j];
continue;
}
if(s[j - c[i]] == 'X') {
dp_forsum[i][j] = dp_forsum[i][j-1] + dp_forward[i][j];
continue;
}
dp_forward[i][j] = (dp_forsum[i-1][j-c[i]-1] - (mx[j-c[i]] == 0 ? 0 : dp_forsum[i-1][mx[j-c[i]]-1]) > 0);
dp_forsum[i][j] = dp_forsum[i][j-1] + dp_forward[i][j];
}
cum++;
}
for(int i=0; i<n - c[k-1] + 1; i++) {
if(ps[1][i + c[k-1] - 1] - (i > 0 ? ps[1][i-1] : 0) == 0) {
if(ps[0][n-1] - ps[0][i + c[k-1] - 1] == 0) {
dp_backward[k-1][i] = 1;
}
}
dp_backsum[k-1][i] = (i == 0 ? 0 : dp_backsum[k-1][i-1]) + dp_backward[k-1][i];
}
for(int i=n-c[k-1]+1; i<n; i++) {
dp_backsum[k-1][i] = (i == 0 ? 0 : dp_backsum[k-1][i-1]) + dp_backward[k-1][i];
}
cum = c[k-1] + 1;
for(int i=k-2; i>=0; i--) {
cum += c[i] - 1;
for(int j=0; j<n-cum; j++) {
if(ps[1][j + c[i] - 1]-(j > 0 ? ps[1][j-1] : 0) > 0) {
dp_backsum[i][j] = (j==0 ? 0 : dp_backsum[i][j-1]) + dp_backward[i][j];
continue;
}
if(s[j + c[i]] == 'X') {
dp_backsum[i][j] = (j==0 ? 0 : dp_backsum[i][j-1]) + dp_backward[i][j];
continue;
}
dp_backward[i][j] = (dp_backsum[i+1][mx2[j + c[i]]] - dp_backsum[i+1][j+c[i]] > 0);
dp_backsum[i][j] = (j==0 ? 0 : dp_backsum[i][j-1]) + dp_backward[i][j];
}
for(int j=n-cum; j<n; j++) {
dp_backsum[i][j] = (j==0 ? 0 : dp_backsum[i][j-1]) + dp_backward[i][j];
}
cum += 2;
}
for(int i=0; i<k; i++) {
for(int j=0; j<n; j++) {
if(j+1<n && s[j+1] == 'X') {
real_sum[i][j] = (j == 0 ? 0 : real_sum[i][j-1]) + real_dp[i][j];
continue;
}
if(j == n-1) {
if(i == k-1) real_dp[i][j] = dp_forward[i][j];
real_sum[i][j] = (j == 0 ? 0 : real_sum[i][j-1]) + real_dp[i][j];
continue;
}
if(i == k-1) {
real_dp[i][j] = dp_forward[i][j] && (ps[0][n-1] - ps[0][j] == 0);
real_sum[i][j] = (j == 0 ? 0 : real_sum[i][j-1]) + real_dp[i][j];
continue;
}
real_dp[i][j] = dp_forward[i][j] && (dp_backsum[i+1][mx2[j+1]] - dp_backsum[i+1][j+1] > 0);
real_sum[i][j] = (j == 0 ? 0 : real_sum[i][j-1]) + real_dp[i][j];
if(real_dp[i][j]) assert(s[j] != '_');
}
}
for(int i=0; i<n; i++) {
for(int j=0; j<k; j++) {
if(real_sum[j][min(n-1, i+c[j]-1)] - (i==0 ? 0 : real_sum[j][i-1]) > 0) {
can[0][i] = 1;
}
}
for(int j=0; j<k-1; j++) {
if(s[i] != 'X' && i>0 && real_sum[j][i-1] && i + c[j+1] < n && (real_sum[j+1][n-1] - real_sum[j+1][i + c[j+1] - 1] > 0)) {
can[1][i] = 1;
}
}
if(s[i] != 'X' && real_sum[0][min(n-1, mx2[i] + c[0] - 1)] - real_sum[0][min(n-1, i + c[0] - 1)] > 0) {
can[1][i] = 1;
}
if(s[i] != 'X' && i > 0 && real_sum[k-1][i-1]) {
can[1][i] = 1;
}
}
for(int i=0; i<k; i++) {
for(int j=0; j<n; j++) {
if(real_dp[i][j]) assert(s[j] != '_');
}
}
}
string ans;
for(int i=0; i<n; i++) {
if(can[0][i] && can[1][i]) ans += "?";
else if(can[0][i]) ans += "X";
else ans += "_";
}
for(int i=0; i<n; i++) {
//assert(!(s[i] == 'X' && ans[i] != 'X'));
//assert(!(s[i] == '_' && ans[i] != '_'));
}
return ans;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |