Submission #969056

#TimeUsernameProblemLanguageResultExecution timeMemory
969056sanoWalk (CEOI06_walk)C++14
100 / 100
370 ms57656 KiB
#include<iostream> #include<vector> #include<queue> #include<string> #include<fstream> #include<algorithm> #include <iomanip> #include<map> #include <set> #include <math.h> #define ll long long #define For(i, n) for(ll i = 0; i < (ll)n; i++) #define ffor(i, a, n) for(ll i = (ll)a; i < (ll)n; i++) #define rfor(i, n) for(ll i = (ll)n; i >= (ll)0; i--) #define rffor(i, a, n) for(ll i = (ll)n; i >= (ll)a; i--) #define vec vector #define ff first #define ss second #define pb push_back #define pii pair<ll, ll> #define NEK 1000000000 #define mod (1e9 + 7) #define rsz resize #define prv 4 #define D 8 using namespace std; struct budova { vec<ll> x; vec<ll> y; ll ind; }; struct udalost { ll y, x, ind, typ; }; bool zorad_udalosti(udalost a, udalost b) { if (a.y == b.y) { if (a.x == b.x) { return a.typ < b.typ; } return a.x < b.x; } return a.y < b.y; } bool zorad_obdlzniky(budova a, budova b) { return a.x[0] < b.x[0]; } ll dist(pii a, pii b) { return abs(a.first - b.first) + abs(a.second - b.second); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); pii finish; cin >> finish.ff >> finish.ss; ll n; cin >> n; vec<budova> p; vec<budova> p_pov; vec<udalost> p2; For(i, n) { ll x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; if (y1 < y2) swap(y1, y2); if (x1 > x2) swap(x1, x2); p_pov.pb({ { x1, x2 }, { y1, y2 }, i }); p.push_back({ {x1, x2}, {y1, y2}, i }); p2.push_back({ y2, x2, i, 0}); p2.push_back({ y1 + 1, x2, i, 1 }); p2.push_back({ y2 - 1, x2 + 1, i, 2 }); p2.push_back({ y1 + 1, x2 + 1, i, 3 }); } p2.push_back({ finish.ss, finish.ff, n, 2 }); vec<vec<ll>> next(n + 1, vec<ll>(2, 0)); sort(p2.begin(), p2.end(), zorad_udalosti); set<pii> s; For(i, p2.size()) { if (p2[i].typ == 0) { s.insert({ p2[i].x, p2[i].ind }); } if (p2[i].typ == 1) { s.erase({ p2[i].x, p2[i].ind }); } if (p2[i].typ == 2) { auto q = s.lower_bound({ p2[i].x, p2[i].ind }); ll dalsi = -1; if (q != s.begin()) { q--; dalsi = q->second; } next[p2[i].ind][0] = dalsi; } if (p2[i].typ == 3) { auto q = s.lower_bound({ p2[i].x, p2[i].ind }); ll dalsi = -1; if (q != s.begin()) { q--; dalsi = q->second; } next[p2[i].ind][1] = dalsi; } } sort(p.begin(), p.end(), zorad_obdlzniky); vec<vec<ll>> dp(n, vec<ll>(2, NEK)); vec<vec<ll>> bt(n + 1, vec<ll>(2, -1)); pii start = { 0, 0 }; For(i, n) { pii roh = { p[i].x[1] + 1, p[i].y[1] - 1 }; ll o = next[p[i].ind][0]; if (o == -1) dp[p[i].ind][0] = dist(start, roh); else { pii roh_1_z = { p_pov[o].x[1] + 1, p_pov[o].y[1] - 1 }; pii roh_2_z = { p_pov[o].x[1] + 1, p_pov[o].y[0] + 1 }; dp[p[i].ind][0] = min(dp[o][0] + dist(roh_1_z, roh), dp[o][1] + dist(roh_2_z, roh)); if (dp[p[i].ind][0] == (dp[o][1] + dist(roh_2_z, roh))) { bt[p[i].ind][0] = 1; } else { bt[p[i].ind][0] = 0; } } roh = { p[i].x[1] + 1, p[i].y[0] + 1 }; o = next[p[i].ind][1]; if (o == -1) dp[p[i].ind][1] = dist(start, roh); else { pii roh_1_z = { p_pov[o].x[1] + 1, p_pov[o].y[1] - 1 }; pii roh_2_z = { p_pov[o].x[1] + 1, p_pov[o].y[0] + 1 }; dp[p[i].ind][1] = min((dp[o][0] + dist(roh_1_z, roh)), (dp[o][1] + dist(roh_2_z, roh))); if (dp[p[i].ind][1] == (dp[o][1] + dist(roh_2_z, roh))) { bt[p[i].ind][1] = 1; } else { bt[p[i].ind][1] = 0; } } } ll o = next[n][0]; if (o == -1) { ll odp = dist(start, finish); cout << odp << '\n'; cout << 2 << '\n'; cout << (finish.ff - start.ff) << ' ' << 0 << ' ' << 0 << ' ' << (finish.ss - start.ss) << '\n'; return 0; } pii roh1 = { p_pov[o].x[1] + 1, p_pov[o].y[1] - 1 }; pii roh2 = { p_pov[o].x[1] + 1, p_pov[o].y[0] + 1 }; ll d1 = dist(roh1, finish); ll d2 = dist(roh2, finish); ll odp = min(dp[o][0] + d1, dp[o][1] + d2); if (odp == dp[o][1] + d2) { bt[n][0] = 1; } else { bt[n][0] = 0; } pii som = { n, 0 }; pii koniec2 = { p_pov[o].x[1] + 1, p_pov[o].y[(bt[som.ff][som.ss] + 1) % 2] + bt[som.ff][som.ss] * 2 - 1 }; pii zaciatok2 = finish; vec<pii> vypis; if (zaciatok2.ff != koniec2.ff) { vypis.push_back({ zaciatok2.ff - koniec2.ff, 0 }); } vypis.push_back({ 0, zaciatok2.ss - koniec2.ss }); som.ss = bt[som.ff][som.ss]; som.ff = o; while (bt[som.ff][som.ss] != -1) { ll n_o = next[som.ff][som.ss]; ll strana = bt[som.ff][som.ss]; pii koniec = { p_pov[n_o].x[1] + 1, p_pov[n_o].y[(strana + 1) % 2] + strana * 2 - 1 }; pii zaciatok = { p_pov[som.ff].x[1] + 1, p_pov[som.ff].y[(som.ss + 1) % 2] + som.ss * 2 - 1 }; vypis.push_back({ zaciatok.ff - koniec.ff, 0 }); vypis.push_back({ 0, zaciatok.ss - koniec.ss }); ll novy_s = strana; ll novy_f = n_o; som.ff = novy_f; som.ss = novy_s; } pii zaciatok = { p_pov[som.first].x[1] + 1, p_pov[som.first].y[(som.second + 1) % 2] + som.second * 2 - 1 }; pii koniec = start; vypis.push_back({ zaciatok.ff - koniec.ff, 0 }); vypis.push_back({ 0, zaciatok.ss - koniec.ss }); cout << odp << '\n'; cout << vypis.size() << '\n'; For(i, vypis.size()) { cout << vypis[vypis.size() - 1 - i].ff << ' ' << vypis[vypis.size() - 1 - i].ss << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...