Submission #1044927

#TimeUsernameProblemLanguageResultExecution timeMemory
1044927ZicrusPaint By Numbers (IOI16_paint)C++17
80 / 100
7 ms604 KiB
#include <bits/stdc++.h> #include "paint.h" using namespace std; typedef long long ll; string solve(string s, vector<int> c, ll n1, ll n, ll k1, ll k) { ll minLen = k-k1-1; for (int i = k1; i < k; i++) minLen += c[i]; if (minLen > n-n1) return "-"; if (minLen <= 0) { for (int i = n1; i < n; i++) { s[i] = '_'; } return s; } ll play = n-n1 - minLen; ll pos = n1; for (int i = k1; i < k; i++) { for (int j = pos+play; j < pos+c[i]; j++) { s[j] = 'X'; } pos += c[i]+1; } for (int i = n1; i < n; i++) { if (s[i] == '.') s[i] = minLen == n-n1 ? '_' : '?'; } return s; } string solveSub(string s, vector<int> c, ll n1, ll n, ll k1, ll k) { string orig = s; ll minLen = max(0ll, k-k1-1); for (int i = k1; i < k; i++) minLen += c[i]; if (minLen > n-n1) return "-"; vector<ll> blacks; for (int i = n1; i < n; i++) { if (s[i] == 'X') blacks.push_back(i); } blacks.push_back(n); ll m = blacks.size(); if (minLen <= 0 && m > 1) return "-"; else if (minLen <= 0) { for (int i = n1; i < n; i++) { s[i] = '_'; } return s; } if (m == 1) return solve(s, c, n1, n, k1, k); ll play = n-n1 - minLen; vector<ll> cOff(k-k1); for (int i = 1; i < k-k1; i++) { cOff[i] = cOff[i-1] + c[i+k1-1] + 1; } unordered_set<ll> idk; bool has = false; ll pos = n1; ll curC = k-k1-1; ll mid = (m-1)/2; while (pos <= n1+play) { while (curC >= 0 && cOff[curC] + pos > blacks[mid]) curC--; if (curC < 0) break; if (cOff[curC] + pos + c[curC+k1] <= blacks[mid]) { pos++; continue; } ll low = cOff[curC] + pos; ll high = low + c[curC+k1]; ll kL = curC; ll kH = k-k1 - curC - 1; ll hash = low | (high << 7) | (kL << 14) | (kH << 21); idk.insert(hash); has = true; pos++; } if (!has) return "-"; /*vector<vector<bool>> poss(m, vector<bool>(k-k1+1)); vector<vector<string>> dp(m, vector<string>(k-k1+1)); for (int i = 0; i < m; i++) { poss[i][0] = true; dp[i][0] = s; for (int j = n1; j < blacks[i]; j++) { dp[i][0][j] = '_'; } } for (int j = k1+1; j <= k && poss[0][j-1]; j++) { dp[0][j] = solve(s, c, n1, blacks[0], k1, j); poss[0][j] = dp[0][j][0] != '-'; }*/ string dummy = ""; bool f = false; for (int i = 0; i < n; i++) dummy += s[i]; for (auto &e : idk) { ll low = e & 127; ll high = (e >> 7) & 127; bool lo = low > n1, hi = high < n; if (lo) low--; if (hi) high++; ll kL = (e >> 14) & 127; ll kH = (e >> 21) & 127; string sol = solveSub(dummy, c, n1, low, k1, k1+kL); if (sol[0] == '-') continue; sol = solveSub(sol, c, high, n, k-kH, k); if (sol[0] == '-') continue; if (lo) { if (sol[low] == 'X') continue; sol[low] = '_'; } if (hi) { if (sol[high-1] == 'X') continue; sol[high-1] = '_'; } for (int i1 = low+lo; i1 < high-hi; i1++) { sol[i1] = 'X'; } for (int i1 = n1; i1 < high; i1++) { if (s[i1] == '.') s[i1] = sol[i1]; else if (sol[i1] == '?' || sol[i1] != s[i1]) s[i1] = '?'; } for (int i1 = high; i1 < n; i1++) { if (s[i1] == '.') s[i1] = sol[i1]; else if (sol[i1] == '?' || sol[i1] != s[i1]) s[i1] = '?'; } f = true; } for (int i = n1; i < n; i++) { if (orig[i] == s[i]) continue; if (orig[i] == 'X') s[i] = 'X'; if (orig[i] == '_') s[i] = '_'; } return f ? s : "-"; } string solve_puzzle(string s, vector<int> c) { ll n = s.size(), k = c.size(); vector<ll> spaces; for (int i = 0; i < n; i++) { if (s[i] == '_') spaces.push_back(i); } spaces.push_back(n); ll m = spaces.size(); vector<vector<bool>> poss(m, vector<bool>(k+1)); vector<vector<string>> dp(m, vector<string>(k+1)); for (int i = 0; i < m; i++) { dp[i][0] = solveSub(s, c, 0, spaces[i], 0, 0); poss[i][0] = dp[i][0][0] != '-'; } for (int j = 1; j <= k; j++) { dp[0][j] = solveSub(s, c, 0, spaces[0], 0, j); poss[0][j] = dp[0][j][0] != '-'; } for (int i = 1; i < m; i++) { for (int j = 1; j <= k; j++) { for (int p = 0; p <= j; p++) { if (!poss[i-1][p]) continue; string sol = solveSub(s, c, spaces[i-1]+1, spaces[i], p, j); bool valid = sol[0] != '-'; if (valid) { if (!poss[i][j]) { dp[i][j] = dp[i-1][p]; for (int i1 = spaces[i-1]+1; i1 < spaces[i]; i1++) { dp[i][j][i1] = sol[i1]; } poss[i][j] = true; } else { for (int i1 = 0; i1 < spaces[i-1]; i1++) { if (dp[i-1][p][i1] == '?' || dp[i-1][p][i1] != dp[i][j][i1]) dp[i][j][i1] = '?'; } for (int i1 = spaces[i-1]+1; i1 < spaces[i]; i1++) { if (sol[i1] == '?' || sol[i1] != dp[i][j][i1]) dp[i][j][i1] = '?'; } } } } } } return dp[m-1][k]; }
#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...