Submission #1196184

#TimeUsernameProblemLanguageResultExecution timeMemory
1196184mmaitiNaval battle (CEOI24_battle)C++20
6 / 100
443 ms108496 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define vi vector<int> #define si set<int> #define vb vector<bool> #define vll vector<ll> #define pii pair<int, int> #define pll pair<ll, ll> #define vvll vector<vector<ll>> struct Ship { int x, y, ix; }; void solve() { // need 3 different ways of sorting // 0. along x + y // 1. along x - y // 2. along the direction of travel (y for N/S, x for E/W) ll N; cin >> N; vector<vector<Ship>> S(4); vector<pii> shipCoord(N); vector<int> shipDir(N); map<char, int> indMap; indMap['N'] = 0; indMap['W'] = 1; indMap['S'] = 2; indMap['E'] = 3; priority_queue<tuple<ll, ll, ll>, vector<tuple<ll, ll, ll>>, greater<tuple<ll, ll, ll>>> pq; int x, y; char c; for (int i = 0; i < N; i++) { cin >> x >> y >> c; shipCoord[i] = {x, y}; shipDir[i] = indMap[c]; S[indMap[c]].push_back({x, y, i}); } vb active(N, true); vector<map<int, map<int, Ship>>> mp1(4), mp2(4), mp3(4), mp4(4); for (int i = 0; i < 4; i++) { for (auto j : S[i]) { int ix = j.x + (i % 2 == 0 ? 1 : -1) * j.y; int key = (i % 2 == 0) ? j.y : j.x; mp1[i][ix][key] = j; } for (auto j : S[(i + 1) % 4]) { int ix = j.x + (i % 2 == 0 ? 1 : -1) * j.y; int key = (i % 2 == 0) ? j.y : j.x; mp2[i][ix][key] = j; } } for (int i : {2, 3}) { for (auto j : S[i]) { int ix = (i == 2 ? j.x : j.y); int rix = (i == 2 ? j.y : j.x); mp3[i][ix][rix] = j; } for (auto j : S[(i + 2) % 4]) { int ix = (i == 2 ? j.x : j.y); int rix = (i == 2 ? j.y : j.x); mp4[i][ix][rix] = j; } } auto pushMp4 = [&](int i, map<int, map<int, Ship>>::iterator &k) { if (k->second.empty()) { k++; return; } auto j = k->second.rbegin(); map<int, Ship>::iterator match; if (mp4[i][k->first].size() == 0) { k++; return; } if (i == 2) { match = mp4[i][k->first].lower_bound(j->second.y); } else { match = mp4[i][k->first].lower_bound(j->second.x); } if (match == mp4[i][k->first].end()) { k++; return; } int diff = (i == 2) ? abs(j->second.y - match->second.y) / 2 : abs(j->second.x - match->second.x) / 2; pq.push(make_tuple(diff, j->second.ix, match->second.ix)); mp4[i][k->first].erase(match); k++; }; auto pushMp2 = [&](int i, map<int, map<int, Ship>>::iterator &k) { if (k->second.empty()) { k++; return; } if (i <= 1) { auto j = k->second.begin(); map<int, Ship>::iterator match; if (mp2[i][k->first].size() == 0) { k++; return; } if (i == 0) match = mp2[i][k->first].lower_bound(j->second.y); else match = mp2[i][k->first].lower_bound(j->second.x); if (match == mp2[i][k->first].begin()) { k++; return; } --match; int xdiff = abs(j->second.x - match->second.x); pq.push(make_tuple(xdiff, j->second.ix, match->second.ix)); } else { auto j = k->second.rbegin(); map<int, Ship>::iterator match; if (mp2[i][k->first].size() == 0) { k++; return; } if (i == 2) match = mp2[i][k->first].lower_bound(j->second.y); else match = mp2[i][k->first].lower_bound(j->second.x); if (match == mp2[i][k->first].end()) { k++; return; } int xdiff = abs(j->second.x - match->second.x); pq.push(make_tuple(xdiff, j->second.ix, match->second.ix)); } k++; }; // setup priority queue first for (int i = 0; i < 4; i++) { // take care of the diagonals for (auto k = mp1[i].begin(); k != mp1[i].end();) { pushMp2(i, k); } } for (int i : {2, 3}) { for (auto k = mp3[i].begin(); k != mp3[i].end();) { pushMp4(i, k); } } auto remDir1 = [&](int dir, int ix, vector<map<int, map<int, Ship>>> &mp) { if (dir % 2 == 0) { int val = shipCoord[ix].first + shipCoord[ix].second; int key = shipCoord[ix].second; mp[dir][val].erase(key); } else { int val = shipCoord[ix].first - shipCoord[ix].second; int key = shipCoord[ix].first; mp[dir][val].erase(key); } }; auto remove = [&](int ix) { int curDir = shipDir[ix]; // remove from mp1, mp2 remDir1(curDir, ix, mp1); remDir1((curDir - 1 + 4) % 4, ix, mp2); // remove from mp3, mp4 if (curDir == 2 || curDir == 3) { // removing from mp3 if (curDir == 2) { mp3[curDir][shipCoord[ix].first].erase(shipCoord[ix].second); } else { mp3[curDir][shipCoord[ix].second].erase(shipCoord[ix].first); } } else { // removing from mp4 if (curDir == 0) { mp4[curDir][shipCoord[ix].first].erase(shipCoord[ix].second); } else { mp4[curDir][shipCoord[ix].second].erase(shipCoord[ix].first); } } }; ll tprev = -1; vector<pll> buffer; auto clearBuffer = [&]() { for (auto pr : buffer) { // remove x and y from the maps // each needs to be removed from mp1, mp2, and either mp3 or mp4 if (active[pr.first]) remove(pr.first); if (active[pr.second]) remove(pr.second); active[pr.first] = false; active[pr.second] = false; // ships were on the same diagonal if ((shipDir[pr.second] - shipDir[pr.first] + 4) % 4 == 1) { // check if the diagonal was x + pr.second or x - pr.second if (shipDir[pr.first] % 2 == 0) { auto it = mp1[shipDir[pr.first]].find(shipCoord[pr.first].first + shipCoord[pr.first].second); pushMp2(shipDir[pr.first], it); } else { auto it = mp1[shipDir[pr.first]].find(shipCoord[pr.first].first - shipCoord[pr.first].second); pushMp2(shipDir[pr.first], it); } } else { // check if it was horizontal or vertical if (shipDir[pr.first] == 2) { auto it = mp3[shipDir[pr.first]].find(shipCoord[pr.first].first); pushMp4(shipDir[pr.first], it); } else { auto it = mp3[shipDir[pr.first]].find(shipCoord[pr.first].second); pushMp4(shipDir[pr.first], it); } } } }; while (!pq.empty()) { auto [t, x, y] = pq.top(); if (t > tprev) { clearBuffer(); buffer.clear(); } else { pq.pop(); if (active[x] && active[y]) { buffer.push_back({x, y}); } } tprev = t; } clearBuffer(); buffer.clear(); for (int i = 0; i < N; i++) { if (active[i]) cout << i + 1 << "\n"; } } int main() { ios_base::sync_with_stdio(0); cin.tie(NULL); solve(); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...