Submission #1275091

#TimeUsernameProblemLanguageResultExecution timeMemory
1275091lmduc270410Mecho (IOI09_mecho)C++20
53 / 100
578 ms7652 KiB
#include <bits/stdc++.h> using namespace std; using pii = pair<int,int>; const int INF = 1e9; int dx[4] = {0,0,-1,1}; int dy[4] = {-1,1,0,0}; 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]; int sx=-1, sy=-1, tx=-1, ty=-1; vector<pii> hives; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(a[i][j] == 'M'){ sx=i; sy=j; } if(a[i][j] == 'D'){ tx=i; ty=j; } if(a[i][j] == 'H'){ hives.push_back({i,j}); } } } // bees_time: minute when bees first occupy cell (hive = 0). D is not enterable -> keep INF. vector<vector<int>> bees(n, vector<int>(n, INF)); queue<pii> q; for(auto &h : hives){ bees[h.first][h.second] = 0; q.push(h); } while(!q.empty()){ auto [x,y] = q.front(); q.pop(); for(int dir=0; dir<4; ++dir){ int nx = x + dx[dir], ny = y + dy[dir]; if(nx<0||nx>=n||ny<0||ny>=n) continue; // bees can spread only into grassy cells (G or M initially). not into T or D or H again. if(a[nx][ny] == 'G' || a[nx][ny] == 'M'){ if(bees[nx][ny] == INF){ bees[nx][ny] = bees[x][y] + 1; q.push({nx, ny}); } } } } // Note: bees[tx][ty] stays INF because bees cannot enter D. // check(t): can Mecho wait t minutes then still reach D? auto can = [&](int t)->bool{ if(bees[sx][sy] <= t) return false; // bees already reach honey while Mecho still there vector<vector<char>> seen(n, vector<char>(n, 0)); queue<pii> curr; curr.push({sx, sy}); seen[sx][sy] = 1; int time = t; // bees have occupied all cells with bees[..] <= time while(!curr.empty()){ // within this minute, Mecho can move up to S steps. // BFS-limited to depth S starting from all nodes in curr (multi-source). queue<pair<pii,int>> bfsq; vector<vector<char>> inbfs(n, vector<char>(n, 0)); // push all current positions as starting nodes (depth 0) int sz = (int)curr.size(); while(sz--){ auto p = curr.front(); curr.pop(); int x = p.first, y = p.second; // If Mecho at any time inside minute reaches home, succeed immediately. if(x == tx && y == ty) return true; // Note: we should allow starting positions only if not currently occupied by bees: if(bees[x][y] <= time) continue; // already unsafe at start of minute bfsq.push({{x,y}, 0}); inbfs[x][y] = 1; } queue<pii> next; // positions Mecho can be at end of this minute while(!bfsq.empty()){ auto cur = bfsq.front(); bfsq.pop(); int x = cur.first.first, y = cur.first.second, d = cur.second; // If he steps onto D at any time -> safe immediately if(x == tx && y == ty) return true; // he can stand here at end of minute only if bees won't reach it at end of minute if(bees[x][y] > time + 1 && !seen[x][y]){ next.push({x,y}); seen[x][y] = 1; } if(d == S) continue; for(int dir=0; dir<4; ++dir){ int nx = x + dx[dir], ny = y + dy[dir]; if(nx<0||nx>=n||ny<0||ny>=n) continue; if(inbfs[nx][ny]) continue; // Mecho can travel on G or D (and M originally treated as G) if(!(a[nx][ny] == 'G' || a[nx][ny] == 'D' || a[nx][ny] == 'M')) continue; // cannot step into a cell that bees already occupy at start of this minute if(bees[nx][ny] <= time) continue; inbfs[nx][ny] = 1; bfsq.push({{nx,ny}, d+1}); } } // advance minute time++; // prepare for next minute curr = move(next); } return false; }; // binary search maximum t (minutes) such that can(t) == true int l = 0, r = 2*n; // as argued, 2*n is safe upper bound in minutes int ans = -1; while(l <= r){ int mid = (l + r) >> 1; if(can(mid)){ ans = mid; l = mid + 1; } else r = mid - 1; } cout << ans << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...