Submission #1004909

#TimeUsernameProblemLanguageResultExecution timeMemory
1004909jonathanirvingsTiles (BOI24_tiles)C++17
100 / 100
199 ms36176 KiB
#include <bits/stdc++.h> using namespace std; int max_line(int N, int, std::vector<int> X, std::vector<int> Y) { map<int, vector<pair<int, int>>> lines_at_x; for (int i = 0; i < N; ++i) { int j = (i + 1) % N; if (X[i] == X[j]) { if (X[i] > 0) { lines_at_x[X[i] - 1]; } lines_at_x[X[i]].push_back(make_pair(min(Y[i], Y[j]), max(Y[i], Y[j]))); } } int answer = 0; vector<int> parity_cnt(2); int odd_lines_cnt = 0; set<tuple<int, int, int>> current_lines; map<int, set<tuple<int, int, int>>::iterator> line_ends_at, line_starts_at; auto erase_current_line = [&] (set<tuple<int, int, int>>::iterator it) { --parity_cnt[get<2>(*it)]; line_starts_at.erase(get<0>(*it)); line_ends_at.erase(get<1>(*it)); if ((get<1>(*it) - get<0>(*it)) % 2 == 1) { --odd_lines_cnt; } current_lines.erase(it); }; auto insert_current_line = [&] (int start_line, int end_line, int parity) { if (line_ends_at.count(start_line)) { auto it = line_ends_at[start_line]; if (get<2>(*it) == parity) { start_line = get<0>(*it); erase_current_line(it); } } if (line_starts_at.count(end_line)) { auto it = line_starts_at[end_line]; if (get<2>(*it) == parity) { end_line = get<1>(*it); erase_current_line(it); } } auto it = current_lines.insert( make_tuple(start_line, end_line, parity)).first; ++parity_cnt[parity]; line_starts_at[start_line] = it; line_ends_at[end_line] = it; if ((end_line - start_line) % 2 == 1) { ++odd_lines_cnt; } }; for (auto [x, lines] : lines_at_x) { if (parity_cnt[1 - x % 2] == 0) { answer = x; } if (lines.size() == 0) { continue; } sort(lines.begin(), lines.end()); int start_line = lines[0].first; for (int i = 0; i < static_cast<int>(lines.size()); ++i) { if (i + 1 == static_cast<int>(lines.size()) || lines[i].second != lines[i + 1].first) { int end_line = lines[i].second; while (start_line < end_line) { auto it = current_lines.upper_bound( make_tuple(start_line, INT_MAX, INT_MAX)); bool entering_polygon = false; if (it == current_lines.begin()) { entering_polygon = true; } else { --it; if (get<1>(*it) <= start_line) { entering_polygon = true; } } if (entering_polygon) { insert_current_line(start_line, end_line, x % 2); break; } int start_cur_line = get<0>(*it); int end_cur_line = get<1>(*it); int parity_cur_line = get<2>(*it); erase_current_line(it); if (x % 2 != parity_cur_line) { return answer; } if (start_cur_line < start_line) { insert_current_line(start_cur_line, start_line, x % 2); } if (end_line < end_cur_line) { insert_current_line(end_line, end_cur_line, x % 2); } start_line = end_cur_line; } if (i + 1 < static_cast<int>(lines.size())) { start_line = lines[i + 1].first; } } } if (odd_lines_cnt > 0) { return answer; } } return answer; } #include <cassert> #include <cstdio> #include <vector> int main() { int N, M; assert(2 == scanf("%d %d", &N, &M)); std::vector<int> X(N), Y(N); for (int i = 0; i < N; ++i) { assert(2 == scanf("%d %d", &X[i], &Y[i])); } int result = max_line(N, M, X, Y); printf("%d\n", result); return 0; }
#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...