제출 #948231

#제출 시각아이디문제언어결과실행 시간메모리
948231Nhoksocqt1가장 긴 여행 (IOI23_longesttrip)C++17
100 / 100
15 ms1232 KiB
#ifndef Nhoksocqt1 #include "longesttrip.h" #endif // Nhoksocqt1 #include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define sz(x) int((x).size()) #define fi first #define se second typedef long long ll; typedef pair<int, int> ii; //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); mt19937 rng(41287); int Random(int l, int r) { return uniform_int_distribution<int>(l, r)(rng); } const int MAXN = 260; #ifdef Nhoksocqt1 bitset<MAXN> adjp[MAXN], idA, idB, bsA, bsB; struct Jury { int n, d; void init(int _n, int _d) { n = _n, d = _d; int u, v; bool check(0); while(cin >> u >> v) { adjp[u][v] = adjp[v][u] = 1; check = 1; } if(!check) { for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { for (int k = j + 1; k < n; ++k) { int cnt = adjp[i][j] + adjp[i][k] + adjp[j][k]; if(cnt < d) { vector<ii> p; p.push_back(ii(i, j)); p.push_back(ii(i, k)); p.push_back(ii(j, k)); while(cnt < d) { int r = Random(0, 2); if(adjp[p[r].fi][p[r].se]) continue; ++cnt; adjp[p[r].fi][p[r].se] = adjp[p[r].se][p[r].fi] = 1; cout << p[r].fi << ' ' << p[r].se << '\n'; } } } } } } } bool are_connected(const vector<int> &A, const vector<int> &B) { bsA = bsB = idA = idB = 0; for (int it = 0; it < sz(A); ++it) { bsA |= adjp[A[it]]; idA[A[it]] = 1; } for (int it = 0; it < sz(B); ++it) { bsB |= adjp[B[it]]; idB[B[it]] = 1; } return ((bsA & idB).count() > 0 || (bsB & idA).count() > 0); } } jury; #endif // Nhoksocqt1 vector<int> A[MAXN]; int nxt[MAXN], numNode; bool adj[MAXN][MAXN], dx[MAXN]; int cntAsk(0); bool check_are_connected(vector<int> A, vector<int> B) { ++cntAsk; #ifdef Nhoksocqt1 return jury.are_connected(A, B); #else return are_connected(A, B); #endif // Nhoksocqt1 } void mergeLine(deque<int> &line1, deque<int> &line2, bool mergeBack1, bool mergeBack2) { if(mergeBack1 && mergeBack2) { while(sz(line2)) { line1.push_back(line2.back()); line2.pop_back(); } return; } if(!mergeBack1 && !mergeBack2) { while(sz(line2)) { line1.push_front(line2.front()); line2.pop_front(); } return; } if(!mergeBack1) swap(line1, line2); while(sz(line2)) { line1.push_back(line2.front()); line2.pop_front(); } } void mergeLine(deque<int> &line1, deque<int> &line2) { if(sz(line2) == 0) return; if(check_are_connected({line1.back()}, {line2.back()})) { mergeLine(line1, line2, 1, 1); return; } if(check_are_connected({line1.back()}, {line2.front()})) { mergeLine(line1, line2, 1, 0); return; } if(check_are_connected({line1.front()}, {line2.back()})) { mergeLine(line1, line2, 0, 1); return; } if(check_are_connected({line1.front()}, {line2.front()})) { mergeLine(line1, line2, 0, 0); return; } vector<int> l1, l2; while(sz(line1)) { l1.push_back(line1.front()); line1.pop_front(); } while(sz(line2)) { l2.push_back(line2.front()); line2.pop_front(); } if(!check_are_connected(l1, l2)) { for (int it = sz(l1) - 1; it >= 0; --it) line1.push_back(l1[it]); return; } int l(0), r(sz(l1) - 1), pos1(-1), pos2(-1); while(l <= r) { vector<int> p; int mid = (l + r) >> 1; for (int it = 0; it <= mid; ++it) p.push_back(l1[it]); if(check_are_connected(p, l2)) { pos1 = mid; r = mid - 1; } else { l = mid + 1; } } l = 0, r = sz(l2) - 1; while(l <= r) { vector<int> p; int mid = (l + r) >> 1; for (int it = 0; it <= mid; ++it) p.push_back(l2[it]); if(check_are_connected({l1[pos1]}, p)) { pos2 = mid; r = mid - 1; } else { l = mid + 1; } } vector<int> p; for (int i = pos1 - 1; i >= 0; --i) p.push_back(l1[i]); for (int i = sz(l1) - 1; i >= pos1; --i) p.push_back(l1[i]); for (int i = pos2; i >= 0; --i) p.push_back(l2[i]); for (int i = sz(l2) - 1; i > pos2; --i) p.push_back(l2[i]); while(sz(line1)) line1.pop_back(); for (int it = sz(p) - 1; it >= 0; --it) line1.push_back(p[it]); } vector<int> longest_trip(int N, int D) { numNode = N; if(D == 3) { vector<int> ans; for (int i = 0; i < numNode; ++i) ans.push_back(i); return ans; } vector<int> ans, id; for (int i = 0; i < numNode; ++i) id.push_back(i); shuffle(id.begin(), id.end(), rng); deque<int> line1, line2; line1.push_back(id[0]); line2.push_back(id[1]); bool needAsk(1); for (int i = 2; i < numNode; ++i) { if(check_are_connected({line1.back()}, {id[i]})) { line1.push_back(id[i]); needAsk = 1; } else if(!needAsk || check_are_connected({line2.back()}, {id[i]})) { line2.push_back(id[i]); needAsk = 0; } else { if(i + 2 < numNode) { bool c1 = check_are_connected({id[i]}, {id[i + 1]}); bool c2 = check_are_connected({id[i]}, {id[i + 2]}); if(c1 && c2) { mergeLine(line1, line2, 1, 1); line2.push_back(id[i + 1]); line2.push_back(id[i]); line2.push_back(id[i + 2]); } else if(!c1 && !c2) { line1.push_back(id[i + 1]); line1.push_back(id[i + 2]); mergeLine(line1, line2, 1, 1); line2.push_back(id[i]); } else { if(!c1) { line1.push_back(id[i + 1]); } else { line1.push_back(id[i + 2]); } mergeLine(line1, line2, 1, 1); if(!c1) { line2.push_back(id[i + 2]); } else { line2.push_back(id[i + 1]); } line2.push_back(id[i]); } i += 2; } else { mergeLine(line1, line2, 1, 1); line2.push_back(id[i]); } needAsk = 1; } } if(sz(line1) < sz(line2)) swap(line1, line2); mergeLine(line1, line2); ans.clear(); while(sz(line1)) { ans.push_back(line1.front()); line1.pop_front(); } return ans; } #ifdef Nhoksocqt1 int main(void) { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); #define TASK "longesttrip" if(fopen(TASK".inp", "r")) { freopen(TASK".inp", "r", stdin); freopen(TASK".out", "w", stdout); } int n, d; cin >> n >> d; jury.init(n, d); vector<int> path = longest_trip(n, d); cout << "CNT ASK: " << cntAsk << '\n'; cout << "ANSWER " << sz(path) << ": "; for (int it = 0; it < sz(path); ++it) cout << path[it] << ' '; cout << '\n'; return 0; } #endif // Nhoksocqt1
#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...