제출 #1354735

#제출 시각아이디문제언어결과실행 시간메모리
1354735takoshanavaPaint By Numbers (IOI16_paint)C++20
32 / 100
1 ms1092 KiB
#include <bits/stdc++.h>
#include "paint.h"
#define pb push_back
using namespace std;

const int N = 2e5 + 5, K = 105;
bool dp[N][K], dp1[N][K], dp2[N][K];
int k, pref[N], n;
vector<int> c;
int wh[N], bl[N], diff[N];

void makedp(string s){
    for(int i = 0; i <= n + 1; i++){
        for(int j = 0; j <= k; j++) dp[i][j] = 0;
    }

    dp[0][0] = 1;

    for(int i = 1; i <= n; i++){
        for(int j = 0; j <= k; j++){
            if(s[i] != 'X' and dp[i - 1][j]) dp[i][j] = 1;            
            if(j > 0){
                int len = c[j - 1];
                int L = i - len + 1;
                if(L >= 1 and pref[i] - pref[L - 1] == 0){
                    if(L == 1){
                        if(j == 1) dp[i][j] = 1;
                    } else if(s[L - 1] != 'X'){
                        dp[i][j] |= dp[L - 2][j - 1];
                    }
                }
            }
        }
    }
}

string solve_puzzle(string s, vector<int> c1) {
    n = s.size();
    k = c1.size();
    c = c1;

    string s1 = " " + s;
    pref[0] = 0;
    for(int i = 1; i <= n; i++) pref[i] = pref[i - 1] + (s1[i] == '_' ? 1 : 0);

    makedp(s1);
    for(int i = 0; i <= n; i++) {
        for(int j = 0; j <= k; j++) dp1[i][j] = dp[i][j];
    }
    reverse(s.begin(), s.end());
    s1 = " " + s;
    reverse(c.begin(), c.end());
    pref[0] = 0;
    for(int i = 1; i <= n; i++) pref[i] = pref[i - 1] + (s1[i] == '_' ? 1 : 0);
    
    makedp(s1);

    for(int i = 0; i <= n + 1; i++){
        for(int j = 0; j <= k; j++) dp2[i][j] = dp[n - i + 1][j];
    }

    reverse(c.begin(), c.end());
    reverse(s.begin(), s.end());
    s = " " + s;

    for(int i = 1; i <= n; i++){
        if(s[i] == 'X') continue;
        for(int j = 0; j <= k; j++){
            if(dp1[i - 1][j] and dp2[i + 1][k - j]) wh[i] = 1;
        }
    }
    for(int i = 0; i <= n + 1; i++) diff[i] = 0;
    for(int i = 0; i <= n + 1; i++) diff[i] = 0;
    for(int t = 0; t < k; t++){
        int len = c[t];
        int p[N]; p[0] = 0;
        for(int i = 1; i <= n; i++) p[i] = p[i-1] + (s[i] == '_' ? 1 : 0);

        for(int l = 1; l + len - 1 <= n; l++){
            int r = l + len - 1;
            if(p[r] - p[l - 1] != 0) continue;
            bool ok1 = (l == 1 and t == 0) or (l > 1 and s[l - 1] != 'X' and dp1[l - 2][t]);
            bool ok2 = (r == n and t == k - 1) or (r < n and s[r + 1] != 'X' and dp2[r + 2][k - t - 1]);

            if(ok1 and ok2){
                diff[l]++;
                diff[r + 1]--;
            }
        }
    }
    int cur = 0;
    for(int i = 1; i <= n; i++){
        cur += diff[i];
        if(cur) bl[i] = 1;
    }
    for(int i = 1; i < s.size(); i++){
        if(s[i] != '.') bl[i] = 2;
    }

    string ans = "";
    for(int i = 1; i <= n; i++){
        if(bl[i] and wh[i]) ans += '?';
        else if(bl[i]) ans += 'X';
        else ans += '_';
    }
    return ans;
}

// signed main(){
//     string s;
//     cin >> s;
//     int k;
//     cin >> k;
//     cout << s.size() << endl;
//     vector<int> a(k);
//     for(int i = 0; i < k; i++) cin >> a[i];
//     cout << solve_puzzle(s, a);
// }
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…