Submission #943119

#TimeUsernameProblemLanguageResultExecution timeMemory
943119simuyuPortals (BOI14_portals)C++14
100 / 100
912 ms73888 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define f first #define s second #define ii pair<int,int> #define qit pair<ii, ll> vector<vector<int> > wallsr, wallsc; //wallsr means c of walls, given r, and vice versa. ii get_walls_with_c(int r, int c) { // stuff with wallsc int small=0, large=wallsc[c].size()-1, mid; while (large-small > 1) { mid = (small+large)/2; if (wallsc[c][mid] > r) { large = mid; // so, r < wallsc[large] , always. (since last is always outside) } else { small = mid; // so, wallsc[small] <= r, always. (since first is always outside) } } if (wallsc[c][small] == r) small--; return ii(wallsc[c][small], wallsc[c][large]); } ii get_walls_with_r(int r, int c) { // stuff with wallsr int small=0, large=wallsr[r].size()-1, mid; while (large-small > 1) { mid = (small+large)/2; if (wallsr[r][mid] > c) { large = mid; // so, r < wallsc[large] , always. (since last is always outside) } else { small = mid; // so, wallsc[small] <= r, always. (since first is always outside) } } if (wallsr[r][small] == c) small--; return ii(wallsr[r][small], wallsr[r][large]); } /* class qit { public: ii f; ll s; qit(ii vals, ll dist) { f = vals; s = dist; } bool operator<(qit b) { return s < b.s; } bool operator>(qit b) { return s > b.s; } const bool operator<(qit b) { return s < b.s; } const bool operator>(qit b) { return s > b.s; } }; */ class cmp { public: int operator()(qit a, qit b) { return greater<ll>()(a.s, b.s); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int r, c; cin >> r >> c; int maze[r+3][c+3]; for (int i=0; i<=r+1; i++) { wallsr.push_back(vector<int>()); wallsr[i].push_back(0); } for (int i=0; i<=c+1; i++) { wallsc.push_back(vector<int>()); wallsc[i].push_back(0); } char temp; ii start; for (int i=1; i<=r; i++) { for (int j=1; j<=c; j++) { cin >> temp; if (temp == '#') { maze[i][j] = -1; wallsr[i].push_back(j); // this will be in ascending order wallsc[j].push_back(i); // but not definitely this (?) } else if (temp == 'C') maze[i][j] = 1; else { maze[i][j] = 0; if (temp == 'S') { start = ii(i, j); } } } } for (int i=0; i<=r+1; i++) { wallsr[i].push_back(c+1); } for (int i=0; i<=c+1; i++) { wallsc[i].push_back(r+1); } // just in case for (int col=1; col<=c; col++) { sort(wallsc[col].begin(), wallsc[col].end()); } bool visited[r+2][c+2]; for (int i=1; i<=r; i++) { for (int j=1; j<=c; j++) { visited[i][j] = false; } } // outline borders for (int i=0; i<=r+1; i++) { visited[i][0] = true; visited[i][c+1] = true; } for (int j=0; j<c+1; j++) { visited[0][j] = true; visited[r+1][j] = true; } priority_queue<qit, vector<qit>, cmp> bfs; bfs.push(qit(start,0)); qit curr = qit(start,0); // temp value ii cpos; ii rwalls, cwalls; int closest; while (!bfs.empty()) { curr = bfs.top(); bfs.pop(); cpos = curr.f; //cout << "CHECKING (" << cpos.f << ',' << cpos.s << "): " << curr.s << endl; //if (cpos.f<0 || cpos.f>r || cpos.s<0 || cpos.s>c) continue; // this means it go out of map bounds, so ignore. if (visited[cpos.f][cpos.s]) continue; visited[cpos.f][cpos.s] = true; if (maze[cpos.f][cpos.s] == 1) { cout << curr.s << '\n'; return 0; } else if (maze[cpos.f][cpos.s] == -1) continue; // means that just ignore yea. // try moving in all four directions normally bfs.push(qit(ii(cpos.f-1, cpos.s), curr.s+1)); bfs.push(qit(ii(cpos.f+1, cpos.s), curr.s+1)); bfs.push(qit(ii(cpos.f, cpos.s-1), curr.s+1)); bfs.push(qit(ii(cpos.f, cpos.s+1), curr.s+1)); // try going to each wall using portal rwalls = get_walls_with_c(cpos.f, cpos.s); cwalls = get_walls_with_r(cpos.f, cpos.s); //cout << "R: " << cpos.f << ", C: " << cpos.s << endl; //cout << "RWALLS: " << rwalls.f << ' ' << rwalls.s << endl; //cout << "CWALLS: " << cwalls.f << ' ' << cwalls.s << endl; // these shldn't need abs, but jic. closest = min( min( abs(cpos.f-rwalls.f) , abs(rwalls.s-cpos.f) ) , min( abs(cpos.s-cwalls.f) , abs(cwalls.s-cpos.s) ) ); //cout << "CLOSEST: " << closest << endl << endl; // try portal gun in all 4 directions bfs.push(qit(ii(rwalls.f+1, cpos.s), curr.s+closest)); bfs.push(qit(ii(rwalls.s-1, cpos.s), curr.s+closest)); bfs.push(qit(ii(cpos.f, cwalls.f+1), curr.s+closest)); bfs.push(qit(ii(cpos.f, cwalls.s-1), curr.s+closest)); } // should never happen... cout << -1 << '\n'; return 0; return 0; }
#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...