Submission #434988

#TimeUsernameProblemLanguageResultExecution timeMemory
434988model_codeFountain Parks (IOI21_parks)C++17
100 / 100
423 ms29468 KiB
/** * Task: parks * Author: Kian Mirjalali * Solution: Solution based on chessboard coloring of cells (trees) * Time: O(n*log(n)+n) where n*log(n) is for just 2 sorts * It computes and keeps the adjacent vertices for each vertex on each direction. */ #include "parks.h" #include <complex> #include <algorithm> #include <iostream> using namespace std; #define tpc(C) template<class C> #define allOf(c) ((c).begin()), ((c).end()) #define fori(i, a, b) for (int i = (a); i < int(b); i++) #define forn(i, n) fori(i, 0, (n)) #define dbg(x) #x << "=" << (x) #define show(x) cerr << dbg(x) << endl #define cmpret(a, b) do { if ((a) != (b)) return ((a) < (b)); } while (false) tpc(C) inline int sz(const C& c) { return c.size(); } typedef vector<int> VI; typedef complex<int> Point; #define X real() #define Y imag() ///////////////////////// const vector<Point> MOVES = { {-2, 0}, {+2, 0}, {0, -2}, {0, +2}, }; const int LEFT = 0; const int RIGHT = 1; const int DOWN = 2; const int UP = 3; ///////////////////////// vector<Point> vertex; inline bool cmp_x_then_y(int i, int j) { const Point& a = vertex[i]; const Point& b = vertex[j]; cmpret(a.X, b.X); return a.Y < b.Y; } inline bool cmp_y_then_x(int i, int j) { const Point& a = vertex[i]; const Point& b = vertex[j]; cmpret(a.Y, b.Y); return a.X < b.X; } ///////////////////////// VI q, mark; inline void enq(int x) { if (mark[x]) return; mark[x] = true; q.push_back(x); } ///////////////////////// int construct_roads(VI x, VI y) { int n = x.size(); vertex.resize(n); forn(i, n) vertex[i] = Point(x[i], y[i]); vector<VI> adj(n, VI(sz(MOVES), -1)); {// Fill adj VI index(n); forn(i, n) index[i] = i; sort(allOf(index), cmp_x_then_y); forn(t, n-1) { int i = index[t]; int j = index[t+1]; if (vertex[i]+MOVES[UP] == vertex[j]) { adj[i][UP] = j; adj[j][DOWN] = i; } } sort(allOf(index), cmp_y_then_x); forn(t, n-1) { int i = index[t]; int j = index[t+1]; if (vertex[i]+MOVES[RIGHT] == vertex[j]) { adj[i][RIGHT] = j; adj[j][LEFT] = i; } } } {// Check connectivity q.clear(); q.reserve(n); mark.assign(n, false); enq(0); for (int tail = 0; tail < sz(q); tail++) for (int nei : adj[q[tail]]) if (nei >= 0) enq(nei); if (sz(q) != n) return 0; } VI u, v, a, b; forn(i, n) { Point pi = vertex[i]; bool is_white_cell = (((pi.X+pi.Y)&2) == 0); { int j = adj[i][RIGHT]; if ((j >= 0) && !((adj[i][UP] >= 0) && (adj[j][UP] >= 0) && is_white_cell)) { u.push_back(i); v.push_back(j); a.push_back(pi.X+1); b.push_back(pi.Y+(is_white_cell?+1:-1)); } } { int j = adj[i][UP]; if ((j >= 0) && !((adj[i][LEFT] >= 0) && (adj[j][LEFT] >= 0) && is_white_cell)) { u.push_back(i); v.push_back(j); a.push_back(pi.X+(is_white_cell?-1:+1)); b.push_back(pi.Y+1); } } } build(u, v, a, b); return 1; }
#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...