제출 #69818

#제출 시각아이디문제언어결과실행 시간메모리
69818evpipisPaint By Numbers (IOI16_paint)C++11
90 / 100
2044 ms187420 KiB
#include "paint.h"
#include <bits/stdc++.h>
using namespace std;

//#define TEST

const int len = 2e5+5;
int pref[len], n, k, white[len], black[len];
bool dp1[len][105][2], vis1[len][105][2], dp2[len][105][2], vis2[len][105][2];
char str[len];
int sz[len];

bool can(int l, int r){
    return (1 <= l && r <= n && pref[r]-pref[l-1] == 0);
}

bool rig(int i, int j, int t){
    //printf("rig\n"), fflush(stdout);
    if (i == n+1 && j == k+1)
        return 1;
    if ((j == k+1 && t == 1) || (i == n+1))
        return 0;
    if (vis1[i][j][t])
        return dp1[i][j][t];

    bool ans = false;
    if (t == 0){
        if (str[i] != 'X')
            ans = rig(i+1, j, 0)|rig(i+1, j, 1);
    }
    else{
        if (str[i] != '_' && can(i, i+sz[j]-1))
            ans = rig(i+sz[j], j+1, 0);
    }

    vis1[i][j][t] = true;
    return dp1[i][j][t] = ans;
}

bool lef(int i, int j, int t){
    //printf("i = %d, j = %d, t = %d\n", i, j, t), fflush(stdout);
    if (i == 0 && j == 0)
        return 1;
    if ((j == 0 && t == 1) || (i == 0))
        return 0;
    if (vis2[i][j][t])
        return dp2[i][j][t];

    bool ans = false;
    if (t == 0){
        if (str[i] != 'X')
            ans = lef(i-1, j, 0)|lef(i-1, j, 1);
    }
    else{
        if (str[i] != '_' && can(i-sz[j]+1, i))
            ans = lef(i-sz[j], j-1, 0);
    }

    vis2[i][j][t] = true;
    return dp2[i][j][t] = ans;
}

string solve_puzzle(string S, vector<int> C) {
    n = S.size(), k = C.size();
    for (int i = 1; i <= k; i++)
        sz[i] = C[i-1];
    for (int i = 1; i <= n; i++)
        str[i] = S[i-1];

    for (int i = 1; i <= n; i++){
        pref[i] = pref[i-1];
        if (str[i] == '_')
            pref[i]++;
    }

    //printf("fine till here\n"), fflush(stdout);

    string out;
    out.resize(n);
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= k+1; j++){
            //printf("i = %d, j = %d\n", i, j), fflush(stdout);
            if (rig(i, j, 0) && (lef(i-1, j-1, 1)|lef(i-1, j-1, 0)))
                white[i] = 1;
            //printf("fir\n"), fflush(stdout);
            if (rig(i, j, 1) && lef(i-1, j-1, 0))
                black[i]++, black[i+sz[j]]--;
            //printf("sec\n"), fflush(stdout);
        }
    }

    for (int i = 1; i <= n; i++)
        black[i] += black[i-1];

    for (int i = 1; i <= n; i++){
        if (str[i] != '.')
            out[i-1] = str[i];
        else if (black[i] && white[i])
            out[i-1] = '?';
        else if (black[i])
            out[i-1] = 'X';
        else
            out[i-1] = '_';
    }

    //for (int i = 1; i <= n; i++)
     //   printf("%d ", rig(i, 1, 1));
    //printf("\n");
    return out;
}

#ifdef TEST
const int S_MAX_LEN = 200 * 1000;
char buf[S_MAX_LEN + 1];

int main() {
    freopen("04", "r", stdin);
    assert(1 == scanf("%s", buf));
    std::string s = buf;
    int c_len;
    assert(1 == scanf("%d", &c_len));
    std::vector<int> c(c_len);
    for (int i = 0; i < c_len; i++) {
        assert(1 == scanf("%d", &c[i]));
    }
    std::string ans = solve_puzzle(s, c);


    printf("%s\n", ans.data());
    return 0;
}
#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...