Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <string>
- #include <cstring>
- #include <utility>
- #include <cstdlib>
- #include <queue>
- #include <deque>
- #include <list>
- #include <set>
- #include <map>
- #include <vector>
- #include <algorithm>
- #include <cmath>
- #include <cassert>
- #include <memory.h>
- #include <ctime>
- #include <cctype>
- using namespace std;
- #define forn(i,n) for (int i = 0; i < int(n); i++)
- #define ford(i,n) for (int i = int(n) - 1; i >= 0; i--)
- #define forv(i,v) for (typeof(v.begin()) i = v.begin(); i != v.end(); i++)
- #define mp make_pair
- #define fs first
- #define sc second
- #define pb push_back
- #define min trgjio
- #define max fgopip
- #define swap kderoe
- #define rand eugtr
- #define srand tkjrg
- typedef long double ld;
- typedef long long ll;
- typedef unsigned char uc;
- typedef unsigned int ui;
- typedef unsigned long long ull;
- typedef pair<int, int> pii;
- typedef vector<int> vi;
- const ld PI = 3.141592653589793238462643l;
- inline int min(int a, int b) {
- return (a < b) ? a : b;
- }
- inline int max(int a, int b) {
- return (a > b) ? a : b;
- }
- inline void swap(int &a, int &b) {
- int c = a;
- a = b;
- b = c;
- }
- int lastrand = 0;
- inline void srand(int a) {
- lastrand = a;
- }
- inline int rand() {
- return abs((lastrand *= 1000000009) += 31);
- }
- void shuffle(vector<int> &a) {
- forn (i, a.size()) {
- swap(a[i], a[rand() % (i + 1)]);
- }
- }
- vector<int> vlist(int n) {
- vector<int> a(n);
- forn (i, n) {
- a[i] = i;
- }
- return a;
- }
- void remove(vector<int> &a, int i) {
- swap(a[i], a[a.size() - 1]);
- a.pop_back();
- }
- int gcd(int a, int b) {
- return a ? gcd(b % a, a) : b;
- }
- struct rect {
- int w, h;
- int zmn, zmx;
- rect() {}
- rect(int n, int m) {
- int d = gcd(n, m);
- w = n / d;
- h = m / d;
- d /= 10;
- zmn = d;
- zmx = 20 * d;
- }
- inline int getw(bool x) {
- return x ? h : w;
- }
- inline int geth(bool x) {
- return x ? w : h;
- }
- };
- struct pos {
- rect r;
- bool put;
- bool rot;
- int x1, y1, x2, y2, z;
- inline void upd() {
- if (put) {
- if (rot) {
- x2 = x1 + r.h * z;
- y2 = y1 + r.w * z;
- } else {
- x2 = x1 + r.w * z;
- y2 = y1 + r.h * z;
- }
- }
- }
- inline void ch() {
- if (x1 > x2) {
- swap(x1, x2);
- }
- if (y1 > y2) {
- swap(y1, y2);
- }
- int w = y2 - y1;
- int h = x2 - x1;
- rot = (r.w > r.h) ^ (w > h);
- z = w / r.getw(rot);
- }
- pos() {
- put = 0;
- z = 1;
- }
- pos(rect a) {
- r = a;
- put = 0;
- z = 1;
- }
- pos(int n, int m) {
- r = rect(n, m);
- put = 0;
- z = 1;
- }
- inline void inv() {
- swap(x1, y1);
- swap(x2, y2);
- rot ^= 1;
- }
- inline void move(int x, int y) {
- x1 += x;
- x2 += x;
- y1 += y;
- y2 += y;
- }
- inline int getw() {
- return r.getw(rot) * z;
- }
- inline int geth() {
- return r.geth(rot) * z;
- }
- };
- inline int sxs(int l1, int r1, int l2, int r2) {
- return max(0, min(r1, r2) - max(l1, l2));
- }
- inline int score(const pos &a, const pos &b) {
- if (!a.put || !b.put) {
- return 0;
- }
- int l = 0;
- if (a.x1 == b.x2 || a.x2 == b.x1) {
- l = sxs(a.y1, a.y2, b.y1, b.y2);
- } else if (a.y1 == b.y2 || a.y2 == b.y1) {
- l = sxs(a.x1, a.x2, b.x1, b.x2);
- } else {
- return 0;
- }
- if (!(a.rot ^ b.rot)) {
- l = -l;
- }
- return l;
- }
- int scorestupid(const vector<pos> &a) {
- int ans = 0;
- forn (i, a.size()) {
- forn (j, i) {
- int s = score(a[i], a[j]);
- ans += s;
- }
- }
- return ans;
- }
- int score(vector<pos> a) {
- int s = 0;
- forn (b, 2) {
- vector<pair<pair<pair<int, bool>, int>, int> > v;
- forn (i, a.size()) {
- v.pb(mp(mp(mp(a[i].x1, 0), a[i].y2), i));
- v.pb(mp(mp(mp(a[i].x2, 1), a[i].y2), i));
- }
- sort(v.begin(), v.end());
- for (int i = 0; i < (int)v.size(); ) {
- int j = i;
- while (j < (int)v.size() && v[j].fs.fs.fs == v[i].fs.fs.fs && v[j].fs.fs.sc == 0) {
- j++;
- }
- int k = j;
- while (k < (int)v.size() && v[k].fs.fs.fs == v[i].fs.fs.fs) {
- k++;
- }
- int l = i, r = j;
- while (l < j && r < k) {
- s += score(a[v[l].sc], a[v[r].sc]);
- if (v[l].fs.sc < v[r].fs.sc) {
- l++;
- } else {
- r++;
- }
- }
- i = k;
- }
- forn (i, a.size()) {
- a[i].inv();
- }
- }
- return s;
- }
- struct alloc {
- int w, h;
- vector<pos> p;
- int s;
- alloc() {
- s = -1000000000;
- }
- alloc(int x, int y, const vector<pos> &a) {
- w = x;
- h = y;
- p = a;
- s = score(a);
- }
- alloc(int x, int y, const vector<pos> &a, int c) {
- w = x;
- h = y;
- p = a;
- s = c;
- }
- inline alloc& bst(const alloc &a) {
- if (a.s > s) {
- *this = a;
- }
- return *this;
- }
- inline alloc& inv() {
- swap(w, h);
- forn (i, p.size()) {
- p[i].rot ^= 1;
- swap(p[i].x1, p[i].y1);
- p[i].upd();
- }
- return *this;
- }
- inline void refh() {
- forn (i, p.size()) {
- p[i].x1 = w - p[i].x1;
- p[i].x2 = w - p[i].x2;
- swap(p[i].x1, p[i].x2);
- }
- }
- inline void refv() {
- forn (i, p.size()) {
- p[i].y1 = h - p[i].y1;
- p[i].y2 = h - p[i].y2;
- swap(p[i].y1, p[i].y2);
- }
- }
- inline alloc& rot(int k) {
- k &= 3;
- if (k == 2) {
- refh();
- refv();
- } else if (k == 1) {
- inv();
- refh();
- } else if (k == 3) {
- inv();
- refv();
- }
- return *this;
- }
- };
- bool operator<(const alloc &a, const alloc &b) {
- return a.s < b.s;
- }
- vector<pos> *srtv;
- bool longer(int a, int b) {
- return (*srtv)[a].geth() * (*srtv)[b].getw() > (*srtv)[b].geth() * (*srtv)[a].getw();
- }
- alloc optimize1(const alloc &t) {
- int www = t.w;
- int ps = t.s;
- vector<pos> a = t.p;
- vector<pair<pair<int, bool>, int> > v;
- vector<int> d;
- vector<int> num;
- forn (i, a.size()) {
- if (a[i].put) {
- v.pb(mp(mp(a[i].x1, 1), i));
- v.pb(mp(mp(a[i].x2, 0), i));
- d.pb(t.h - a[i].y2);
- } else {
- d.pb(-1);
- num.pb(i);
- }
- }
- sort(v.begin(), v.end());
- sort(num.begin(), num.end());
- set<pair<int, int> > s;
- forn (i, v.size() - 1) {
- int k = v[i].sc;
- if (v[i].fs.sc) {
- s.insert(mp(a[k].y1, k));
- } else {
- s.erase(mp(a[k].y1, k));
- }
- if (s.size()) {
- for (set<pair<int, int> >::iterator i1 = s.begin(), i2 = ++s.begin(); i2 != s.end(); i1 = i2++) {
- int u1 = i1->sc, u2 = i2->sc;
- d[u1] = min(d[u1], a[u2].y1 - a[u1].y2 - 1);
- }
- }
- }
- vector<pair<int, int> > l;
- forn (i, a.size()) {
- if (a[i].put) {
- l.pb(mp(d[i], i));
- }
- }
- sort(l.begin(), l.end());
- do {
- int q1 = rand() % (1 + rand() % l.size());
- int q2 = rand() % l.size();
- swap(l[q1].fs, l[q2].fs);
- swap(l[q1].sc, l[q2].sc);
- } while (rand() % 10 == 0);
- ford (qwe, l.size()) {
- int i = l[qwe].sc;
- int H = d[i], W = a[i].x2 - a[i].x1 - 2;
- if (H > 0 && W > 0) {
- int x0 = a[i].x1 + 1;
- int y0 = a[i].y2;
- bool q = a[i].rot;
- int last = i;
- while (1) {
- q ^= 1;
- int chi = -1, chz = 0, sc = -1000000000;
- forn (k, num.size()) {
- pos &t = a[num[k]];
- int w = t.r.getw(q);
- int h = t.r.geth(q);
- int lz = t.r.zmn, rz = t.r.zmx;
- rz = min(rz, W / w);
- rz = min(rz, H / h);
- if (lz > rz) {
- continue;
- }
- w *= rz;
- h *= rz;
- int s = -((W - w) * H + h * W);
- if (s > sc) {
- chi = k;
- chz = rz;
- sc = s;
- }
- }
- if (chi < 0) {
- break;
- }
- pos t = a[num[chi]];
- t.y1 = y0;
- t.z = chz;
- t.put = 1;
- t.rot = q;
- t.x1 = x0;
- t.upd();
- int last1 = num[chi];
- int lb = 0, rb = www;
- vector<int> lv, rv;
- forn (i, a.size()) {
- if (a[i].put) {
- if (sxs(a[i].y1, a[i].y2, t.y1, t.y2)) {
- if (a[i].x2 <= t.x1) {
- if (a[i].x2 > lb) {
- lb = a[i].x2;
- lv.clear();
- }
- if (a[i].x2 == lb) {
- lv.pb(i);
- }
- }
- if (a[i].x1 >= t.x2) {
- if (a[i].x1 < rb) {
- rb = a[i].x1;
- rv.clear();
- }
- if (a[i].x1 == rb) {
- rv.pb(i);
- }
- }
- }
- }
- }
- int x[3];
- x[0] = x0;
- x[1] = lb;
- x[2] = rb - chz * t.r.getw(q);
- pos bstpos = t;
- int bstsc = -1000000000;
- remove(num, chi);
- forn (i, 3) {
- t.x1 = x[i];
- t.upd();
- int sc = 0;
- sc += score(t, a[last]);
- forn (i, lv.size()) {
- sc += score(t, a[lv[i]]);
- }
- forn (i, rv.size()) {
- sc += score(t, a[rv[i]]);
- }
- if (sc > bstsc) {
- bstsc = sc;
- bstpos = t;
- }
- }
- forn (i, a.size()) {
- if (a[i].put && sxs(a[i].x1, a[i].x2, bstpos.x1, bstpos.x2) && a[i].y2 <= bstpos.y1) {
- d[i] = min(d[i], bstpos.y1 - a[i].y2 - 1);
- }
- }
- a[last1] = bstpos;
- y0 = t.y2;
- H -= t.y2 - t.y1;
- last = last1;
- ps += bstsc;
- }
- }
- }
- return alloc(t.w, t.h, a);
- }
- alloc optimize1_T(alloc v, int t) {
- if (t) {
- v.inv();
- }
- alloc w = optimize1(v);
- if (t) {
- w.inv();
- }
- return w;
- }
- alloc optimize1_all(alloc w) {
- alloc ans = w;
- forn (q, 2) {
- alloc v = w;
- for (int i = 0; ; i++) {
- int ss = v.s;
- v = optimize1_T(v, (i + q) & 1);
- if (v.s == ss) {
- break;
- }
- }
- ans.bst(v);
- }
- return ans;
- }
- alloc optimize1_time(alloc v, double TL) {
- alloc ans = v;
- int mxt = 0, time = clock();
- for (int cnt = 0; time + mxt < TL * CLOCKS_PER_SEC; cnt++) {
- int time0 = time;
- ans.bst(optimize1_all(v));
- time = clock();
- mxt = max(mxt, time - time0);
- }
- return ans;
- }
- alloc solve1(const alloc &v, int maxw = -1, int minw = -1, int maxh = -1, int minh = -1) {
- vector<pos> p = v.p;
- int ps = 0;
- int n = p.size();
- if (maxw == -1) {
- maxw = 1 + rand() % (1 + rand() % v.w);
- }
- if (minw == -1) {
- minw = 1 + rand() % (1 + rand() % maxw);
- }
- if (maxh == -1) {
- maxh = 1 + rand() % (1 + rand() % v.h);
- }
- if (minh == -1) {
- minh = 1 + rand() % (1 + rand() % maxh);
- }
- vector<int> num = vlist(n);
- shuffle(num);
- vector<int> a;
- bool q = rand() & 1;
- for (int i = 0; ; i++) {
- int x0 = (i ? p[a[i - 1]].x2 : 0), y0 = 0;
- int chi = -1, chz = 0, sc = -1000000000;
- forn (bad, 2) {
- forn (k, num.size()) {
- pos &t = p[num[k]];
- int w = t.r.getw(q);
- int h = t.r.geth(q);
- int lz = t.r.zmn, rz = t.r.zmx;
- rz = min(rz, (v.w - x0) / w);
- rz = min(rz, (v.h - y0) / h);
- if (!bad) {
- rz = min(rz, maxw / w);
- lz = max(lz, (minw - 1) / w + 1);
- }
- if (!i) {
- if (!bad) {
- rz = min(rz, maxh / h);
- lz = max(lz, (minh - 1) / h + 1);
- }
- } else {
- rz = min(rz, (p[a[i - 1]].y2 - y0 - 1) / h);
- }
- if (lz > rz) {
- continue;
- }
- int z[2] = {lz, rz}, s[2] = {0, 0};
- forn (g, 2) {
- s[g] = 0;
- if (i) {
- s[g] += z[g] * h;
- }
- }
- int bt = (s[1] > s[0]);
- if (s[1] == s[0]) {
- z[bt] = lz + rand() % (rz - lz + 1);
- }
- if (s[bt] > sc) {
- chi = k;
- chz = z[bt];
- sc = s[bt];
- }
- }
- if (chi >= 0) {
- break;
- }
- }
- if (chi < 0) {
- break;
- }
- pos &t = p[num[chi]];
- a.pb(num[chi]);
- remove(num, chi);
- shuffle(num);
- t.x1 = x0;
- t.y1 = y0;
- t.z = chz;
- t.put = 1;
- t.rot = q;
- t.upd();
- if (i) {
- ps += score(t, p[a[i - 1]]);
- }
- q ^= 1;
- }
- vector<int> a1;
- while (1) {
- // forn (j, a.size()) {
- // cerr << a[j] << ' ';
- // }
- // cerr << endl;
- a1.clear();
- int i = 0;
- while (i < (int)a.size()) {
- int a1s = a1.size();
- bool q = p[a[i]].rot ^ 1;
- if (a1s) {
- q = p[a1[a1s - 1]].rot ^ 1;
- }
- bool tan = 1;
- int j = i;
- while (j < (int)a.size() &&p[a[j]].rot == p[a[i]].rot) {
- j++;
- }
- while (j < (int)a.size() && p[a[j]].rot != q) {
- j++;
- tan = 0;
- }
- int j1 = j + 1;
- while (j1 < (int)a.size() && p[a[j]].rot == p[a[j1]].rot) {
- j1++;
- }
- j--;
- j1--;
- int x0 = (a1.size() ? p[a1[a1s - 1]].x2 : (i ? p[a[i - 1]].x2 + (p[a[i - 1]].rot == q) : 0));
- int y0 = p[a[i]].y2 + (!tan);
- int chi = -1, chz = 0, sc = -1000000000;
- forn (bad, 2) {
- forn (k, num.size()) {
- pos &t = p[num[k]];
- int w = t.r.getw(q);
- int h = t.r.geth(q);
- int lz = t.r.zmn, rz = t.r.zmx;
- rz = min(rz, (v.w - x0) / w);
- rz = min(rz, (v.h - y0) / h);
- if (!a1s) {
- if (!bad) {
- rz = min(rz, maxh / h);
- lz = max(lz, (minh - 1) / h + 1);
- }
- } else {
- rz = min(rz, (p[a1[a1s - 1]].y2 - y0 - 1) / h);
- }
- lz = max(lz, (p[a[j]].x2 - x0) / w + 1);
- if (!bad) {
- if (j1 == (int)a.size()) {
- rz = min(rz, maxw / w);
- lz = max(lz, (minw - 1) / w + 1);
- } else {
- rz = min(rz, (p[a[j1]].x2 - x0 - 1) / w);
- }
- }
- if (lz > rz) {
- continue;
- }
- int z[2] = {lz, rz}, s[2] = {0, 0};
- forn (g, 2) {
- s[g] = 0;
- s[g] -= z[g] * w;
- if (a1.size()) {
- s[g] += z[g] * h;
- }
- }
- int bt = (s[1] > s[0]);
- if (s[bt] > sc) {
- chi = k;
- chz = z[bt];
- sc = s[bt];
- }
- }
- if (chi >= 0) {
- break;
- }
- }
- if (chi < 0) {
- if (a1.size()) {
- break;
- } else {
- i++;
- continue;
- }
- }
- pos &t = p[num[chi]];
- t.x1 = x0;
- t.y1 = y0;
- t.z = chz;
- t.put = 1;
- t.rot = q;
- t.upd();
- if (!a1s) {
- forn (e, i) {
- if (p[a[e]].y2 >= t.y2) {
- a1.pb(a[e]);
- }
- }
- }
- a1.pb(num[chi]);
- remove(num, chi);
- shuffle(num);
- ps += score(t, p[a[i]]);
- if (a1s) {
- ps += score(t, p[a1[a1s - 1]]);
- }
- while (i < (int)a.size() && p[a[i]].x2 < t.x2) {
- i++;
- }
- }
- if (!a1.size()) {
- break;
- }
- forn (i, a.size()) {
- if (p[a[i]].x2 > p[a1[a1.size() - 1]].x2) {
- a1.pb(a[i]);
- }
- }
- a = a1;
- }
- return alloc(v.w, v.h, p);
- }
- alloc solve1_T(alloc v, bool t = -1, int maxw = -1, int minw = -1, int maxh = -1, int minh = -1) {
- if (t == -1) {
- t = rand() & 1;
- }
- if (t) {
- v.inv();
- }
- alloc w = solve1(v, maxw, minw, maxh, minh);
- if (t) {
- w.inv();
- }
- return w;
- }
- alloc main1(const alloc &v0, double TL, int t = -1, int maxw = -1, int minw = -1, int maxh = -1, int minh = -1) {
- alloc ans = v0;
- int mxt = 0, time = clock(), mxo = 10;
- for (int cnt = 0; time + mxt < TL * 0.99 * CLOCKS_PER_SEC; cnt++) {
- alloc v = solve1_T(v0, t, maxw, minw, maxh, minh);
- int s = v.s;
- if (s + 2 * mxo > ans.s) {
- alloc w = optimize1_all(v);
- mxo = max(mxo, v.s - s);
- ans.bst(w);
- }
- int time0 = time;
- time = clock();
- mxt = max(mxt, time - time0);
- }
- return optimize1_time(ans, TL);
- }
- alloc main1_ch(const alloc &v0, double TL, double preTL = -1) {
- if (preTL < -0.5) {
- preTL = TL / 5;
- }
- alloc ans[2];
- forn (i, 2) {
- ans[i] = main1(v0, (i + 1) * preTL / 2, i);
- }
- bool b = (ans[1].s > ans[0].s);
- return main1(v0, TL, b).bst(ans[b]);
- }
- alloc getdata() {
- int k, N, M;
- cin >> N >> M >> k;
- N *= 10;
- M *= 10;
- vector<pos> V(k);
- forn (i, k) {
- int w, h;
- cin >> w >> h;
- V[i] = pos(10 * w, 10 * h);
- }
- return alloc(N, M, V, 0);
- }
- void write(const alloc &a) {
- forn (i, a.p.size()) {
- if (!a.p[i].put) {
- puts("-1 -1 -1 -1");
- } else {
- cout
- << 0.1 * a.p[i].x1 << ' '
- << 0.1 * a.p[i].y1 << ' '
- << 0.1 * a.p[i].x2 << ' '
- << 0.1 * a.p[i].y2 << endl;
- }
- }
- cerr << score(a.p) << endl;
- }
- const double TL = 4.95;
- int main() {
- freopen("input.txt", "rt", stdin);
- freopen("output.txt", "wt", stdout);
- int rnd = time(NULL);
- cerr << rnd << endl;
- // int rnd = 33385462;
- srand(rnd);
- alloc v0 = getdata();
- write(main1_ch(v0, TL));
- cerr << (double)clock() / CLOCKS_PER_SEC << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement