제출 #1275098

#제출 시각아이디문제언어결과실행 시간메모리
1275098lmduc270410Mecho (IOI09_mecho)C++20
46 / 100
1097 ms15440 KiB
#include <bits/stdc++.h> using namespace std; using pii = pair<int,int>; const int MAXN = 805; const int INF = 1e9; int n, k; string a[MAXN]; int dx[4] = {0,0,-1,1}; int dy[4] = {-1,1,0,0}; int bees_time[MAXN][MAXN]; int sx=-1, sy=-1, tx=-1, ty=-1; inline int id(int x, int y){ return x * n + y; } inline int xi(int idd){ return idd / n; } inline int yi(int idd){ return idd % n; } void compute_bees_time(){ for(int i=0;i<n;i++) for(int j=0;j<n;j++) bees_time[i][j] = INF; queue<pii> q; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(a[i][j] == 'H'){ bees_time[i][j] = 0; q.push({i,j}); } if(a[i][j] == 'M'){ sx=i; sy=j; } if(a[i][j] == 'D'){ tx=i; ty=j; } } } while(!q.empty()){ auto cur = q.front(); q.pop(); int x = cur.first, y = cur.second; 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(!(a[nx][ny]=='G' || a[nx][ny]=='M')) continue; if(bees_time[nx][ny] == INF){ bees_time[nx][ny] = bees_time[x][y] + 1; q.push({nx, ny}); } } } // bees_time[tx][ty] stays INF (bees don't enter D) } // --- token arrays to avoid memset --- static int seen_mark[MAXN*MAXN]; static int inbfs_mark[MAXN*MAXN]; static int seen_token = 2; static int inbfs_token = 4; // static arrays to avoid allocations static int curr_arr[MAXN*MAXN]; static int next_arr[MAXN*MAXN]; static int qnodes[MAXN*MAXN]; static int qdepth[MAXN*MAXN]; bool can(int t){ if(sx==-1 || tx==-1) return false; if(bees_time[sx][sy] <= t) return false; int curr_sz = 0; curr_arr[curr_sz++] = id(sx, sy); ++seen_token; if(seen_token==0){ ++seen_token; ++inbfs_token; } ++inbfs_token; if(inbfs_token==0){ ++inbfs_token; ++seen_token; } int time = t; while(curr_sz){ // BFS multi-source limited to depth k int qhead = 0, qtail = 0; ++inbfs_token; if(inbfs_token==0){ ++inbfs_token; ++seen_token; } // push all current for(int i=0;i<curr_sz;i++){ int pos = curr_arr[i]; int x = xi(pos), y = yi(pos); if(bees_time[x][y] <= time) continue; // unsafe at start if(x==tx && y==ty) return true; if(inbfs_mark[pos] != inbfs_token){ inbfs_mark[pos] = inbfs_token; qnodes[qtail] = pos; qdepth[qtail] = 0; ++qtail; } } int next_sz = 0; while(qhead < qtail){ int curpos = qnodes[qhead]; int d = qdepth[qhead]; ++qhead; int x = xi(curpos), y = yi(curpos); if(x==tx && y==ty) return true; if(bees_time[x][y] > time + 1 && seen_mark[curpos] != seen_token){ seen_mark[curpos] = seen_token; next_arr[next_sz++] = curpos; } if(d == k) 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; char ch = a[nx][ny]; if(!(ch=='G' || ch=='D' || ch=='M')) continue; if(bees_time[nx][ny] <= time) continue; int nid = id(nx,ny); if(inbfs_mark[nid] == inbfs_token) continue; inbfs_mark[nid] = inbfs_token; qnodes[qtail] = nid; qdepth[qtail] = d+1; ++qtail; } } time++; ++seen_token; if(seen_token==0){ ++seen_token; ++inbfs_token; } // swap curr and next curr_sz = next_sz; for(int i=0;i<next_sz;i++) curr_arr[i] = next_arr[i]; } return false; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); if(!(cin >> n >> k)) return 0; for(int i=0;i<n;i++) cin >> a[i]; compute_bees_time(); // set upper bound r more tightly: int r; if(bees_time[sx][sy] == INF) r = n * n; // bees never reach M -> cap at n*n else r = min(n * n, bees_time[sx][sy] - 1); // cannot wait >= bees_time[sx][sy] int l = 0, 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...