Submission #1275113

#TimeUsernameProblemLanguageResultExecution timeMemory
1275113socialfox123Mecho (IOI09_mecho)C++20
97 / 100
1095 ms10492 KiB
#include <bits/stdc++.h> using namespace std; using pii = pair<int,int>; const int INF = 1e9; int dr[4] = {-1,1,0,0}; int dc[4] = {0,0,-1,1}; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N, S; if(!(cin >> N >> S)) return 0; vector<string> a(N); for(int i=0;i<N;i++) cin >> a[i]; vector<vector<int>> beeDist(N, vector<int>(N, INF)); queue<pii> q; pii start = {-1,-1}, home = {-1,-1}; for(int r=0;r<N;r++){ for(int c=0;c<N;c++){ if(a[r][c]=='H'){ beeDist[r][c] = 0; q.push({r,c}); } else if(a[r][c]=='M') start = {r,c}; else if(a[r][c]=='D') home = {r,c}; } } // BFS for bees: they can move into any cell that is NOT 'T' and NOT 'D' while(!q.empty()){ auto [r,c] = q.front(); q.pop(); int d = beeDist[r][c]; for(int k=0;k<4;k++){ int nr=r+dr[k], nc=c+dc[k]; if(nr<0||nr>=N||nc<0||nc>=N) continue; if(a[nr][nc]=='T' || a[nr][nc]=='D') continue; // bees can't go through trees or into D if(beeDist[nr][nc] > d+1){ beeDist[nr][nc] = d+1; q.push({nr,nc}); } } } // make D effectively safe: set beeDist[D] = INF (already INF because we didn't allow bees into D), // but ensure it explicitly: beeDist[home.first][home.second] = INF; // Helper: check if wait = w is possible auto can = [&](int w)->bool{ // must be safe at start cell at time w if(beeDist[start.first][start.second] <= w) return false; // visited_global: cells we've already used as start-of-minute in previous iterations (avoid re-visiting forever) vector<vector<char>> used(N, vector<char>(N, 0)); queue<pii> frontier; // cells that are start-of-minute at current time t used[start.first][start.second] = 1; frontier.push(start); int t = w; // current minute index (we start moving at minute t = w) // If start is itself D (unlikely by problem statement), success if(start == home) return true; while(!frontier.empty()){ // BFS limited to depth S from all frontier sources, allowed to step only through cells with beeDist > t vector<pii> nextFront; // will be start-of-minute for t+1 (only cells with beeDist > t+1) queue<pair<pii,int>> qq; vector<vector<char>> seen(N, vector<char>(N,0)); // seen within this minute's multi-source S-BFS // push all frontier sources as depth 0 int fsz = frontier.size(); while(fsz--){ auto p = frontier.front(); frontier.pop(); qq.push({p,0}); seen[p.first][p.second] = 1; } while(!qq.empty()){ auto cur = qq.front(); qq.pop(); int r = cur.first.first, c = cur.first.second, depth = cur.second; // If we reach home at any time, success if(r==home.first && c==home.second) return true; if(depth == S) continue; // can't go deeper this minute for(int k=0;k<4;k++){ int nr=r+dr[k], nc=c+dc[k]; if(nr<0||nr>=N||nc<0||nc>=N) continue; if(seen[nr][nc]) continue; // Mecho cannot go on trees or on H (hive). He can go on G, M, D. if(a[nr][nc]=='T' || a[nr][nc]=='H') continue; // He cannot step into a cell that has already been occupied by bees at start of minute t: if(beeDist[nr][nc] <= t) continue; seen[nr][nc] = 1; qq.push({{nr,nc}, depth+1}); } } // from seen (cells reached within <=S steps this minute), construct nextFront of cells that survive to next minute for(int r=0;r<N;r++){ for(int c=0;c<N;c++){ if(!seen[r][c]) continue; // If any reached cell is home we would have returned earlier. if(r==home.first && c==home.second) return true; // to survive to next minute (i.e., at start of minute t+1) Mecho's cell must have beeDist > t+1 if(beeDist[r][c] > t+1){ if(!used[r][c]){ used[r][c] = 1; nextFront.push_back({r,c}); } } } } // push nextFront into frontier queue for(auto &p: nextFront) frontier.push(p); // increment minute t++; } return false; }; // Binary search maximum w int lo = 0, hi = N*N + 5; // hi is exclusive upper bound; safe big int ans = -1; while(lo <= hi){ int mid = lo + (hi-lo)/2; if(can(mid)){ ans = mid; lo = mid+1; } else hi = mid-1; } if(ans < 0) cout << -1 << "\n"; else cout << ans << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...