結果
問題 | No.2177 Recurring ab |
ユーザー | MasKoaTS |
提出日時 | 2022-09-18 14:59:12 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 9,607 bytes |
コンパイル時間 | 5,177 ms |
コンパイル使用メモリ | 291,056 KB |
実行使用メモリ | 13,952 KB |
最終ジャッジ日時 | 2024-09-15 02:49:55 |
合計ジャッジ時間 | 11,365 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | TLE | - |
testcase_01 | -- | - |
testcase_02 | -- | - |
testcase_03 | -- | - |
testcase_04 | -- | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
コンパイルメッセージ
In constructor 'Point::Point(int, int)', inlined from 'Point* getRectangle(V<Point>&)' at main.cpp:128:29: main.cpp:74:25: warning: 'y' may be used uninitialized [-Wmaybe-uninitialized] 74 | this->y = y; | ~~~~~~~~^~~ main.cpp: In function 'Point* getRectangle(V<Point>&)': main.cpp:117:16: note: 'y' was declared here 117 | int x, y; | ^ In constructor 'Point::Point(int, int)', inlined from 'Point* getRectangle(V<Point>&)' at main.cpp:128:29: main.cpp:73:25: warning: 'x' may be used uninitialized [-Wmaybe-uninitialized] 73 | this->x = x; | ~~~~~~~~^~~ main.cpp: In function 'Point* getRectangle(V<Point>&)': main.cpp:117:13: note: 'x' was declared here 117 | int x, y; | ^
ソースコード
#include <math.h> #include <bits/stdc++.h> #include <atcoder/all> using namespace std; using namespace atcoder; #define print(n) cout << (n) << endl #define fprint(n) cout << setprecision(16) << (n) << endl #define ceil_div(a, b) (((a) - 1) / (b) + 1) #define rep(i, l, n) for (int i = (l); i < (n); i++) #define itrep(itr, st) for (auto itr = st.begin(); itr != st.end(); itr++) #define ite(i, a) for (auto& i : a) #define all(x) x.begin(), x.end() #define lb lower_bound #define ub upper_bound #define lbi(A, x) (ll)(lb(all(A), x) - A.begin()) #define ubi(A, x) (ll)(ub(all(A), x) - A.begin()) using str = string; using ll = long long; using Pair = pair<int, int>; using mint = modint1000000007; using Mint = modint998244353; template <class T> using V = vector<T>; template <class T> using VV = V<V<T> >; template <class T> using PQ = priority_queue<T, V<T>, greater<T> >; template <class T> using PQR = priority_queue<T>; template <class T> using BIT = fenwick_tree<T>; const ll INF = 4611686018427387903; const int inf = 2147483647; const ll mod = 1000000007; const ll MOD = 998244353; template <class T> inline V<T> getList(int n) { V<T> res(n); rep(i, 0, n) { cin >> res[i]; }return res; } template <class T> inline VV<T> getGrid(int m, int n) { VV<T> res(m, V<T>(n)); rep(i, 0, m) { res[i] = getList<T>(n); }return res; } template <class T> inline void prints(V<T>& vec) { if (vec.size() == 0)return; cout << vec[0]; rep(i, 1, vec.size()) { cout << ' ' << vec[i]; } cout << '\n'; } inline V<int> dtois(string& s) { V<int> vec = {}; ite(e, s) { vec.push_back(e - '0'); } return vec; } inline V<int> atois(string& s) { V<int> vec = {}; ite(e, s) { vec.push_back(e - 'a'); } return vec; } inline V<int> Atois(string& s) { V<int> vec = {}; ite(e, s) { vec.push_back(e - 'A'); } return vec; } #define TIME 900 //グローバル変数 int N, M, C; struct Point; V<Point> points; V<BIT<int> > xbt; V<BIT<int> > ybt; V<BIT<int> > nxbt; V<BIT<int> > nybt; V<BIT<int> > lxbt; V<BIT<int> > lybt; V<BIT<int> > lnxbt; V<BIT<int> > lnybt; V<V<Point> > ans = {}; //答えとなる点の集合 //2乗 inline int squ(int x) { return x * x; } //二次元平面上の点 struct Point { int x; int y; Point(void) { x = 0; y = 0; } Point(int x, int y) { this->x = x; this->y = y; } int weight(void) const{ return squ(this->x - C) + squ(this->y - C) + 1; } bool operator<(const Point other) const { int a = this->weight(); int b = other.weight(); if (a == b) { return tie(this->x, this->y) < tie(other.x, other.y); } return a > b; } }; //時間計測系 using chrono::duration_cast; using chrono::milliseconds; using chrono::system_clock; inline int getnow() { return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); } //乱数系 mt19937 mt{ random_device{}() }; uniform_int_distribution<> rand03(0, 3); //3点から長方形の最後の1点を得る Point* getRectangle(V<Point>& point_vec) { assert(point_vec.size() == 3); set<int> xst = {}; set<int> yst = {}; set<Point> pst = {}; for (Point p : point_vec) { pst.insert(p); xst.insert(p.x); yst.insert(p.y); } if (xst.size() != 2 or yst.size() != 2) { return NULL; } int x, y; itrep(itr_x, xst) { itrep(itr_y, yst) { Point p = Point(*itr_x, *itr_y); if (pst.find(p) != pst.end()) { continue; } x = p.x; y = p.y; } } Point* ret = new Point(x, y); return ret; } //4点を長方形をなすように並び替えた配列を得る V<Point> getSortedRectangle(V<Point>& point_vec) { assert(point_vec.size() == 4); V<Point> ret = { point_vec[0] }; set<Point> pst = { point_vec[0] }; rep(i, 0, 3) { for (Point p : point_vec) { if (p.x != ret[i].x and p.y != ret[i].y) { continue; } if (pst.find(p) != pst.end()) { continue; } ret.push_back(p); pst.insert(p); break; } } /*if (ret.size() != 4) { cout << "point_vec" << endl; for (Point p : point_vec) { cout << p.x << ' ' << p.y << endl; } cout << "pst" << endl; itrep(itr, pst) { Point p = *itr; cout << p.x << ' ' << p.y << endl; } cout << "ret" << endl; for (Point p : ret) { cout << p.x << ' ' << p.y << endl; } assert(false); }*/ return ret; } //長方形の最後の1点を調べて追加(まっすぐ) void addStraightRectangle(int i, int j, int k) { V<Point> point_vec = { points[i],points[j],points[k] }; Point* p = getRectangle(point_vec); if (p == NULL or xbt[p->y].sum(p->x, p->x + 1) != 0) { return; } V<Point> vec = { *p,points[i],points[j],points[k] }; vec = getSortedRectangle(vec); //作る長方形が条件を満たしているかチェック vec.push_back(*p); bool flag = true; rep(l, 0, 4) { //x座標が同じ場合 if (vec[l].x == vec[l + 1].x) { int x = vec[l].x; int y1 = min(vec[l].y, vec[l + 1].y); int y2 = max(vec[l].y, vec[l + 1].y); flag &= (ybt[x].sum(y1 + 1, y2) == 0) & (lybt[x].sum(y1, y2) == 0); } //y座標が同じ場合 if (vec[l].y == vec[l + 1].y) { int y = vec[l].y; int x1 = min(vec[l].x, vec[l + 1].x); int x2 = max(vec[l].x, vec[l + 1].x); flag &= (xbt[y].sum(x1 + 1, x2) == 0) & (lxbt[y].sum(x1, x2) == 0); } if (flag == false) { break; } } if (flag == false) { return; } //長方形・点の追加 rep(l, 0, 4) { //x座標が同じ場合 if (vec[l].x == vec[l + 1].x) { int x = vec[l].x; int y1 = min(vec[l].y, vec[l + 1].y); int y2 = max(vec[l].y, vec[l + 1].y); rep(y, y1, y2) { lybt[x].add(y, 1); } } //y座標が同じ場合 if (vec[l].y == vec[l + 1].y) { int y = vec[l].y; int x1 = min(vec[l].x, vec[l + 1].x); int x2 = max(vec[l].x, vec[l + 1].x); rep(x, x1, x2) { lxbt[y].add(x, 1); } } } vec.pop_back(); ans.push_back(vec); points.push_back(*p); xbt[p->y].add(p->x, 1); ybt[p->x].add(p->y, 1); int nx = p->x + p->y, ny = p->x - p->y + (N - 1); nxbt[ny].add(nx, 1); nybt[nx].add(ny, 1); M++; } //長方形の最後の1点を調べて追加(斜め) void addDiagonalRectangle(int i, int j, int k) { Point p1 = Point(points[i].x + points[i].y, points[i].x - points[i].y + (N - 1)); Point p2 = Point(points[j].x + points[j].y, points[j].x - points[j].y + (N - 1)); Point p3 = Point(points[k].x + points[k].y, points[k].x - points[k].y + (N - 1)); V<Point> point_vec = { p1,p2,p3 }; Point* p = getRectangle(point_vec); if (p == NULL or nxbt[p->y].sum(p->x, p->x + 1) != 0) { return; } V<Point> vec = { *p,p1,p2,p3 }; vec = getSortedRectangle(vec); //作る長方形が条件を満たしているかチェック vec.push_back(*p); bool flag = true; rep(l, 0, 4) { //x座標が同じ場合 if (vec[l].x == vec[l + 1].x) { int x = vec[l].x; int y1 = min(vec[l].y, vec[l + 1].y); int y2 = max(vec[l].y, vec[l + 1].y); flag &= (nybt[x].sum(y1 + 1, y2) == 0) & (lnybt[x].sum(y1, y2) == 0); } //y座標が同じ場合 if (vec[l].y == vec[l + 1].y) { int y = vec[l].y; int x1 = min(vec[l].x, vec[l + 1].x); int x2 = max(vec[l].x, vec[l + 1].x); flag &= (nxbt[y].sum(x1 + 1, x2) == 0) & (lnxbt[y].sum(x1, x2) == 0); } if (flag == false) { break; } } if (flag == false) { return; } //長方形・点の追加 rep(l, 0, 4) { //x座標が同じ場合 if (vec[l].x == vec[l + 1].x) { int x = vec[l].x; int y1 = min(vec[l].y, vec[l + 1].y); int y2 = max(vec[l].y, vec[l + 1].y); rep(y, y1, y2) { lnybt[x].add(y, 1); } } //y座標が同じ場合 if (vec[l].y == vec[l + 1].y) { int y = vec[l].y; int x1 = min(vec[l].x, vec[l + 1].x); int x2 = max(vec[l].x, vec[l + 1].x); rep(x, x1, x2) { lnxbt[y].add(x, 1); } } } vec.pop_back(); nxbt[p->y].add(p->x, 1); nybt[p->x].add(p->y, 1); //まっすぐの点に直す V<Point> nvec = {}; for (Point np : vec) { int x = (np.x + np.y - (N - 1)) >> 1; int y = (np.x - np.y + (N - 1)) >> 1; nvec.push_back({ x,y }); } ans.push_back(nvec); int x = (p->x + p->y - (N - 1)) >> 1; int y = (p->x - p->y + (N - 1)) >> 1; points.push_back({ x,y }); xbt[y].add(x, 1); ybt[x].add(y, 1); M++; } //メイン int main(void) { //時間計測開始 int time_limit = getnow() + TIME; //入力 cin >> N >> M; C = (N - 1) >> 1; points = V<Point>(M); xbt = V<BIT<int> >(N, BIT<int>(N)); ybt = V<BIT<int> >(N, BIT<int>(N)); nxbt = V<BIT<int> >(N << 1, BIT<int>(N << 1)); nybt = V<BIT<int> >(N << 1, BIT<int>(N << 1)); rep(i, 0, M) { int x, y; cin >> x >> y; xbt[y].add(x, 1); ybt[x].add(y, 1); points[i] = Point(x, y); int nx = x + y, ny = x - y + (N - 1); nxbt[ny].add(nx, 1); nybt[nx].add(ny, 1); } //sort(all(points)); //既に追加した線分の集合 lxbt = V<BIT<int> >(N, BIT<int>(N - 1)); lybt = V<BIT<int> >(N, BIT<int>(N - 1)); lnxbt = V<BIT<int> >(N << 1, BIT<int>((N << 1) - 1)); lnybt = V<BIT<int> >(N << 1, BIT<int>((N << 1) - 1)); //時間の許す限り探索 while (true) { //3点の組み合わせを調べる rep(i, 0, M - 2) { rep(j, i + 1, M - 1) { rep(k, j + 1, M) { //時間の許す限り探索 if (getnow() >= time_limit) { goto OUTPUT; } //長方形の最後の1点を調べて追加(まっすぐ) addStraightRectangle(i, j, k); //長方形の最後の1点を調べて追加(斜め) addDiagonalRectangle(i, j, k); } } } } OUTPUT: //答えを出力 cout << ans.size() << endl; for (V<Point> vec : ans) { cout << vec[0].x << ' ' << vec[0].y; rep(i, 1, 4) { cout << ' ' << vec[i].x << ' ' << vec[i].y; } cout << '\n'; } return 0; }