#include "bits/stdc++.h" using namespace std; #define int long long #define ld long double #define ll long long #define st first #define nd second #define pb push_back #define eb emplace_back #define sz(x) (int)(x).size() #define all(x) begin(x),end(x) #define FOR(i,l,r) for(int i = (l); i <= (r); i++) #define ROF(i,r,l) for (int i = (r); i >= (l); i--) auto& operator<<(auto&o, pair<auto,auto>p) { return o << "(" << p.st << ", " << p.nd << ")"; } auto operator<<(auto&o, auto x)->decltype(end(x), o) { o << "{"; int i =0; for (auto e : x) o << ","+!i++ << e; return o << "}"; } #ifdef LOCAL #define debug(x...) cerr << "[" #x "]: ", [](auto...$) { \ ((cerr << $ << "; "), ...) << endl; }(x) #else #define debug(...) {} #endif #define rep(i, a, b) for (int i = (a); i < (b); i++) using pii = pair<int, int>; using vi = vector<int>; const int inf = 1e9 + 7; #define x st #define y nd struct Ball { pii pos; int p, q; void add(int d) { if (p >= d) { p -= d; } else if (p < d && q >= d) { p = 0; } else { p = min(d - q, d - p); } q += d; } bool inside(pii pp) const { int dx = pp.x - pos.x; int dy = pp.y - pos.y; int d = max<int>(abs(dx), abs(dy)); return p <= d && d <= q; } }; pii rot45(pii p) { return {p.x + p.y, p.y - p.x}; } pii rev45(pii p) { assert((p.st - p.nd) % 2 == 0); assert((p.st + p.nd) % 2 == 0); return { (p.st - p.nd) / 2, (p.st + p.nd) / 2 }; } const int N = 55; int n, d[N]; pii s; Ball balls[N]; int ori_dist(pii a, pii b) { int dx = a.x - b.x; int dy = a.y - b.y; return abs(dx) + abs(dy); } signed main() { cin.tie(0)->sync_with_stdio(0); cin >> n; cin >> s.x >> s.y; int sum = 0; FOR(i, 1, n - 1) { cin >> d[i]; sum += d[i]; } if (sum % 2 != (s.x + s.y) % 2) { cout << "NO\n"; return 0; } s = rot45(s); balls[n] = Ball{s, 0, 0}; ROF(i, n - 1, 0) { balls[i] = balls[i + 1]; balls[i].add(d[i]); } pii now{0, 0}; if (!balls[0].inside(now)) { cout << "NO\n"; return 0; } FOR(i, 0, n) { debug(i, balls[i].pos, balls[i].p, balls[i].q); } vector<pii> ans{now}; FOR(i, 1, n - 1) { vi xs, ys; for (int dx : {-1, +1}) { for (int len : {balls[i + 1].p, balls[i + 1].q}) { xs.pb(balls[i + 1].pos.x + dx * len); ys.pb(balls[i + 1].pos.y + dx * len); } xs.pb(now.st + dx * d[i]); ys.pb(now.nd + dx * d[i]); } int X = sz(xs); rep(j, 0, X) FOR(dx, -1, +1) xs.pb(xs[j] + dx); int Y = sz(ys); rep(j, 0, Y) FOR(dy, -1, +1) ys.pb(ys[j] + dy); sort(all(xs)); sort(all(ys)); xs.erase(unique(all(xs)), end(xs)); ys.erase(unique(all(ys)), end(ys)); debug(xs, ys); Ball b{now, d[i], d[i]}; bool done = false; for (int x : xs) for (int y : ys) { // if ((abs(x) + abs(y)) % 2 == 1) { // continue; // } if (b.inside({x, y}) && balls[i + 1].inside({x, y})) { now = {x, y}; done = true; } } debug(now, done); assert(done); if ((abs(now.x) + abs(now.y)) % 2 != 0) { assert(false); } ans.pb(now); } cout << "YES\n"; assert(sz(ans) == n); for (pii &p : ans) { p = rev45(p); cout << p.st << ' ' << p.nd << '\n'; } debug(ans); rep(i, 1, n) { debug(ori_dist(ans[i - 1], ans[i]), d[i]); assert(ori_dist(ans[i - 1], ans[i]) == d[i]); } return 0; }