Submission #919600

#TimeUsernameProblemLanguageResultExecution timeMemory
919600StefanL2005Paint By Numbers (IOI16_paint)C++14
100 / 100
536 ms161616 KiB
#include <bits/stdc++.h> using namespace std; ifstream in("file.in"); int get_between(int i, int j, vector<int> &Pre_Sum) { if (i > j) swap(i, j); if (i == 0) return Pre_Sum[j]; return Pre_Sum[j] - Pre_Sum[i - 1]; } bool check_block_borders(int i, int j, string &s) { int l = s.length(); if (i <= 0 || s[i - 1] != 'X') if (j >= l - 1 || s[j + 1] != 'X') return true; return false; } int check_block_P (int i, int j, int add, vector<vector<int>> &P, string &s, vector<int> &Pre_Sum) { if (j - add + 1 < 0) return 0; if (get_between(j - add + 1, j, Pre_Sum) > 0) return 0; if (!check_block_borders(j - add + 1, j, s)) return 0; if (j - add > 0 && P[i - 1][j - add - 1] == 0) return 0; if (j - add <= 0 && i != 1) return 0; return 1; } int check_block_S (int i, int j, int add, vector<vector<int>> &S, string &s, vector<int> &Pre_Sum) { int l = s.length(); if (j + add - 1 >= l) return 0; if (get_between(j, j + add - 1, Pre_Sum) > 0) return 0; if (!check_block_borders(j, j + add - 1, s)) return 0; if (j + add < l - 1 && S[i - 1][j + add + 1] == 0) return 0; if (j + add >= l - 1 && i != 1) return 0; return 1; } void first_line_init(int i, int j, string &s, vector<vector<int>> &M) { while (i != j) { M[0][i] = 1; if (s[i] == 'X') { M[0][i] = 0; break; } if (i < j) i++; else i--; } } bool can_end_1 (int i, int j, vector<vector<int>> &P, vector<vector<int>> &S) { int k = P.size() - 1, l = P[0].size(); bool p1 = (i == 0 && j == 0) || (i > 0 && P[j][i - 1]); bool p2 = (i == l - 1 && j == k) || (i < l - 1 && S[k - j][i + 1]); return p1 && p2; } bool can_end_2 (int i, int j, int add, vector<vector<int>> &P, vector<vector<int>> &S) { int k = P.size() - 1, l = P[0].size(); bool p1 = ((j <= 1 && i == 1) || (j > 1 && P[i - 1][j - 2])); bool p2 = ((j + add >= l - 1 && k == i) || (j + add < l - 1 && S[k - i][j + add + 1])); return (p1 && p2); } void fill_ans (string &ans, int j, int add) { for (int i = j; i < j + add; i++) if (ans[i] == '_') ans[i] = '?'; } string solve_puzzle (string s, vector<int> c) { int k = c.size(), l = s.length(); bool change_back = false; string ans; vector<int> Pre_Sum; vector<vector<int>> P, S; Pre_Sum = vector<int> (l, 0); P = S = vector<vector<int>> (k + 1, vector<int> (l, 0)); ans.assign(l, '_'); for (int i = 0; i < l; i++) { if (s[i] == 'X') ans[i] = 'X'; if (s[i] == '_') Pre_Sum[i]++; if (i > 0) Pre_Sum[i]+= Pre_Sum[i - 1]; } first_line_init(0, l, s, P); for (int i = 1; i <= k; i++) for (int j = 0; j < l; j++) { bool _Case = 0, XCase; if (j > 0) _Case = P[i][j - 1]; XCase = check_block_P(i, j, c[i - 1], P, s, Pre_Sum); switch(s[j]) { case '_':{ P[i][j] = _Case; break; } case 'X':{ P[i][j] = XCase; break; } case '.':{ P[i][j] = _Case || XCase; break; } } } first_line_init(l - 1, -1, s, S); for (int i = 1; i <= k; i++) for (int j = l - 1; j >= 0; j--) { bool _Case = 0, XCase; if (j + 1 < l) _Case = S[i][j + 1]; XCase = check_block_S(i, j, c[k - i], S, s, Pre_Sum); switch(s[j]) { case '_':{ S[i][j] = _Case; break; } case 'X':{ S[i][j] = XCase; break; } case '.':{ S[i][j] = _Case || XCase; break; } } } for (int i = 0; i < l; i++) { bool ok = true; for (int j = 0; j <= k && ok; j++) if (can_end_1(i, j, P, S)) ok = false; if (ok) ans[i] = 'X'; } for (int i = 1; i <= k; i++) { int add = c[i - 1]; for (int j = 0; j <= l - add; j++) { if (get_between(j, j + add - 1, Pre_Sum) > 0) continue; if (!check_block_borders(j, j + add - 1, ans)) continue; if (!can_end_2(i, j, add, P, S)) continue; fill_ans(ans, j, add); } } return ans; }

Compilation message (stderr)

paint.cpp: In function 'std::string solve_puzzle(std::string, std::vector<int>)':
paint.cpp:97:10: warning: unused variable 'change_back' [-Wunused-variable]
   97 |     bool change_back = false;
      |          ^~~~~~~~~~~
#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...