제출 #713473

#제출 시각아이디문제언어결과실행 시간메모리
713473boris_mihovPaint By Numbers (IOI16_paint)C++17
100 / 100
1329 ms99904 KiB
#include "paint.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>

typedef long long llong;
const int MAXN = 200000 + 10;
const int MAXK = 100 + 10;
const int INF  = 1e9;

int n, k;
std::string s;
int lens[MAXK];
bool dp[MAXN][MAXK];
bool bl[MAXN][MAXK];
bool dp2[MAXN][MAXK];
bool bl2[MAXN][MAXK];
int max[MAXN];
int can2[MAXN];
int can[MAXN];

bool f(int pos, int curr)
{
    if (pos >= n) 
    {
        return (curr == k);
    }

    if (bl[pos][curr])
    {
        return dp[pos][curr];
    }

    bl[pos][curr] = true;
    dp[pos][curr] = false;
    if (s[pos] != '_' && curr < k && can[pos] >= lens[curr] && (pos + lens[curr] == n || s[pos + lens[curr]] != 'X'))
    {
        dp[pos][curr] |= f(pos + lens[curr] + 1, curr + 1);
    }

    if (s[pos] != 'X')
    {
        dp[pos][curr] |= f(pos + 1, curr);
    }

    return dp[pos][curr];
}

bool hasX[MAXN];
bool f2(int pos, int curr)
{
    if (pos < 0) 
    {
        return (curr == -1);
    }

    if (curr == -1)
    {
        return !hasX[pos];
    }

    if (bl2[pos][curr])
    {
        return dp2[pos][curr];
    }

    bl2[pos][curr] = true;
    dp2[pos][curr] = false;
    if (s[pos] != '_' && curr < k && can2[pos] >= lens[curr] && (pos - lens[curr] == -1 || s[pos - lens[curr]] != 'X'))
    {
        dp2[pos][curr] |= f2(pos - lens[curr] - 1, curr - 1);
    }

    if (s[pos] != 'X')
    {
        dp2[pos][curr] |= f2(pos - 1, curr);
    }

    return dp2[pos][curr];
}

bool canBeBlack[MAXN];
bool canBeWhite[MAXN];
std::string solve_puzzle(std::string S, std::vector <int> c) 
{
    s = S;
    n = s.size();
    k = c.size();

    for (int i = 0 ; i < k ; ++i)
    {
        lens[i] = c[i];
    }

    for (int i = 0 ; i < n ; ++i)
    {
        hasX[i] = ((i != 0 && hasX[i - 1]) || s[i] == 'X');
        if (s[i] == '_') can2[i] = 0;
        else if (i == 0) can2[i] = 1;
        else can2[i] = can2[i - 1] + 1;
    }

    for (int i = n - 1 ; i >= 0 ; --i)
    {
        if (s[i] == '_') can[i] = 0;
        else can[i] = can[i + 1] + 1;
    }

    for (int i = 0 ; i < n ; ++i)
    {
        if (s[i] == 'X') continue;
        for (int j = 0 ; j <= k ; ++j)
        {
            if (f2(i - 1, j - 1) && f(i + 1, j))
            {
                canBeWhite[i] = true;
            }        
        }
    }

    for (int i = 0 ; i < n ; ++i)
    {
        if (s[i] == '_' || (i > 0 && s[i - 1] == 'X')) continue;
        for (int j = 0 ; j < k ; ++j)
        {
            if (f2(i - 2, j - 1) && can[i] >= lens[j] && i + lens[j] <= n && (i + lens[j] == n || s[i + lens[j]] != 'X') && f(i + lens[j] + 1, j + 1))
            {
                max[i] = std::max(max[i], lens[j]);
            }       
        }
    }

    int left = 0;   
    for (int i = 0 ; i < n ; ++i)
    {
        left = std::max(left - 1, max[i]);
        if (left > 0) canBeBlack[i] = true;
    }

    std::string ans;
    ans.resize(n);

    for (int i = 0 ; i < n ; ++i)
    {
        if (canBeBlack[i] && canBeWhite[i]) ans[i] = '?';
        else if (canBeBlack[i]) ans[i] = 'X';
        else if (canBeWhite[i]) ans[i] = '_';
        else assert(false);
    }

    return ans;
}
#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...