Submission #1293720

#TimeUsernameProblemLanguageResultExecution timeMemory
1293720vincentbucourt1Paint By Numbers (IOI16_paint)C++20
100 / 100
877 ms34220 KiB
#include "paint.h" #include <bits/stdc++.h> using namespace std; int N, Q; enum INFO {ON, OFF, BOTH}; vector<INFO> info; // NOTE: 1-idx // NOTE: blocks: 1-idx vector<int> prefOff; // NOTE: exc vector<vector<bool>> prefDP, suffDP; // NOTE: [exc][exc] vector<int> diffOn, diffOff; // NOTE: [l, r) updates int cntOff (int l, int r) { return prefOff[r+1] - prefOff[l]; } std::string solve_puzzle(std::string specified, std::vector<int> blocks) { N = (int)specified.size(); Q = (int)blocks.size(); info.assign(N+20, BOTH); for (int i = 0; i < N; i++) { if (specified[i] == 'X') { info[i+1] = ON; } else if (specified[i] == '_') { info[i+1] = OFF; } else { info[i+1] = BOTH; } } // cerr << "info: "; // for (int i = 1; i <= N; i++) cerr << info[i] << " "; // cerr << "\n"; vector<int> tempBlocks(Q+20); for (int q = 0; q < Q; q++) { tempBlocks[q+1] = blocks[q]; } swap(blocks, tempBlocks); prefOff.assign(N+20, 0); for (int i = 1; i <= N; i++) { prefOff[i+1] = prefOff[i] + (info[i] == OFF); } // cerr << "prefOff: "; // for (int i = 1; i <= N; i++) cerr << prefOff[i] << " "; // cerr << "\n"; prefDP.assign(N+20, vector<bool>(Q+20, false)); prefDP[1][1] = true; for (int i = 1; i <= N; i++) { for (int q = 1; q <= Q+1; q++) { if (prefDP[i][q]) { if (info[i] != ON) { prefDP[i+1][q] = true; } if (q <= Q) { int blockOn = blocks[q]; // NOTE: [i, i + blockOn - 1]: ON, [i + blockOn, i + blockOn]: OFF if (i + blockOn - 1 <= N && cntOff(i, i + blockOn - 1) == 0 && info[i + blockOn] != ON) { prefDP[i + blockOn + 1][q+1] = true; } } } } } suffDP.assign(N+20, vector<bool>(Q+20, false)); suffDP[N][Q] = true; suffDP[N+1][Q] = true; for (int i = N; i >= 1; i--) { for (int q = Q; q >= 0; q--) { if (suffDP[i][q]) { if (info[i] != ON) { suffDP[i-1][q] = true; } int blockOn = blocks[q]; // NOTE: [i - blockOn + 1, i]: ON if (q >= 1 && i == N && cntOff(i - blockOn + 1, i) == 0) { suffDP[i - blockOn][q-1] = true; } // NOTE: [i - blockOn, i - 1]: ON, [i, i]: OFF if (q >= 1 && 1 <= i - blockOn && cntOff(i - blockOn, i - 1) == 0 && info[i] != ON) { suffDP[i - blockOn - 1][q-1] = true; } } } } cerr << "prefDP tests:\n"; cerr << " exp: 1, got: " << prefDP[8][2] << "\n"; cerr << "suffDP tests:\n"; cerr << " exp: 1, got: " << suffDP[1][0] << "\n"; diffOn.assign(N+20, 0); diffOff.assign(N+20, 0); cerr << "inters:\n"; for (int i = 1; i <= N; i++) { for (int q = 1; q <= Q+1; q++) { // NOTE: [i, i]: OFF if (prefDP[i][q] && info[i] != ON && suffDP[i][q-1]) { // cerr << " " << i << " " << q << "\n"; diffOff[i]++, diffOff[i+1]--; } if (q <= Q) { int blockOn = blocks[q]; // NOTE: [i, i + blockOn - 1]: ON, [i + blockOn, i + blockOn]: OFF if (prefDP[i][q] && i + blockOn - 1 <= N && cntOff(i, i + blockOn - 1) == 0 && info[i + blockOn] != ON && suffDP[i + blockOn][q]) { // cerr << " " << i << " " << i + blockOn - 1 << "\n"; diffOn[i]++, diffOn[i + blockOn]--; diffOff[i + blockOn]++, diffOff[i + blockOn + 1]--; } } } } for (int i = 1; i <= N; i++) { diffOn[i+1] += diffOn[i]; diffOff[i+1] += diffOff[i]; if (info[i] == ON) diffOn[i] = 1; if (info[i] == OFF) diffOff[i] = 1; } cerr << "diffOn: "; for (int d : diffOn) cerr << d << " "; cerr << "\ndiffOff: "; for (int d : diffOff) cerr << d << " "; cerr << "\n"; string ans; for (int i = 1; i <= N; i++) { if (diffOn[i] && diffOff[i]) { ans += '?'; } else if (diffOn[i] && !diffOff[i]) { ans += 'X'; } else if (!diffOn[i] && diffOff[i]) { ans += '_'; } else { // shouldnt happen assert(false); } } return ans; }

Compilation message (stderr)

paint.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
paint_c.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
#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...