Submission #218121

#TimeUsernameProblemLanguageResultExecution timeMemory
218121emil_physmathPaint By Numbers (IOI16_paint)C++17
90 / 100
17 ms10496 KiB
#include "paint.h"
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;
const int maxN = 5000;
const int maxK = 100;

int n, k;
int dp[2][maxN][maxK], pref[2][maxN][maxK];
int whites[maxN], blacks[maxN];
string s;
vector<int> c;

inline int Whites(int l, int r) { return l > r ? 0 : whites[r] - (l ? whites[l - 1] : 0); }
inline int Blacks(int l, int r) { return l > r ? 0 : blacks[r] - (l ? blacks[l - 1] : 0); }
void Init1(int dp[maxN][maxK], int pref[maxN][maxK])
{
    for (int i = 0; i < n; ++i)
    {
        if (i - c[0] + 1 >= 0 && !Whites(i - c[0] + 1, i) && !Blacks(0, i - c[0]))
            dp[i][0] = true;
        for (int j = 1; j < k; ++j)
            if (i - c[j] + 1 >= 0 && !Whites(i - c[j] + 1, i))
                if (i - c[j] - 1 >= 0 && pref[i - c[j] - 1][j - 1])
                    if (i - c[j] < 0 || s[i - c[j]] != 'X')
                        dp[i][j] = true;
        for (int j = 0; j < k; ++j)
            pref[i][j] = ((i && s[i] != 'X') ? pref[i - 1][j] : false) | dp[i][j];
    }
}
void Init2(int dp[maxN][maxK], int pref[maxN][maxK])
{
    for (int i = n - 1; i >= 0; --i)
    {
        if (i + c[k - 1] - 1 < n && !Whites(i, i + c[k - 1] - 1) && !Blacks(i + c[k - 1], n - 1))
            dp[i][k - 1] = true;
        for (int j = k - 2; j >= 0; --j)
            if (i + c[j] - 1 < n && !Whites(i, i + c[j] - 1))
                if (i + c[j] + 1 < n && pref[i + c[j] + 1][j + 1])
                    if (i + c[j] >= n || s[i + c[j]] != 'X')
                        dp[i][j] = true;
        for (int j = 0; j < k; ++j)
            pref[i][j] = ((i + 1 < n && s[i] != 'X') ? pref[i + 1][j] : false) | dp[i][j];
    }
}
string solve_puzzle(string s_, vector<int> c_) {
    s = s_;
    c = c_;
    n = s.length(); k = c.size();
    for (int i = 0; i < n; ++i)
        whites[i] = (i ? whites[i - 1] : 0) + (s[i] == '_'),
        blacks[i] = (i ? blacks[i - 1] : 0) + (s[i] == 'X');
    Init1(dp[0], pref[0]);
    Init2(dp[1], pref[1]);
    /*for (int i = 0; i < n; ++i)
        for (int j = 0; j < k; ++j)
            cerr << "dp[0][" << i << "][" << j << "] = " << dp[0][i][j] << '\n';
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < k; ++j)
            cerr << "dp[1][" << i << "][" << j << "] = " << dp[1][i][j] << '\n';*/
    vector<int> can_(n), canX(n);
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < k; ++j)
        {
            bool poss = true;
            if (j)
            {
                if (i - 2 < 0 || !pref[0][i - 2][j - 1]) poss = false;
            }
            else if (Blacks(0, i - 1))
                poss = false;
            if (j + 1 < k)
            {
                if (i + c[j] + 1 >= n || !pref[1][i + c[j] + 1][j + 1]) poss = false;
            }
            else if (Blacks(i + c[j], n - 1))
                poss = false;
            if (i + c[j] - 1 >= n || Whites(i, i + c[j] - 1))
                poss = false;
            if (i && s[i - 1] == 'X') poss = false;
            if (i + c[j] < n && s[i + c[j]] == 'X') poss = false;
            if (poss)
            {
                ++canX[i];
                if (i + c[j] < n) --canX[i + c[j]];
            }
        }
    for (int i = 1; i < n; ++i)
        canX[i] += canX[i - 1];
    for (int i = 0; i < n; ++i)
    {
        if (i + 1 < n && pref[1][i + 1][0] && !Blacks(0, i))
        {
            can_[i] = true;
            continue;
        }
        for (int j = 0; j + 1 < k; ++j)
            if (i && s[i] != 'X' && pref[0][i - 1][j] && i + 1 < n && pref[1][i + 1][j + 1])
            {
                can_[i] = true;
                break;
            }
        if (i && pref[0][i - 1][k - 1] && !Blacks(i, n - 1))
            can_[i] = true;
    }
    string res(n, '?');
    for (int i = 0; i < n; ++i)
        if ((bool)can_[i] ^ (bool)canX[i])
            res[i] = (canX[i] ? 'X' : '_');
    return res;
}
#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...