Submission #1254837

#TimeUsernameProblemLanguageResultExecution timeMemory
1254837shawnchang51Maze (JOI23_ho_t3)C++17
0 / 100
0 ms328 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const int INF = 1e9; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int R,C,N; if(!(cin>>R>>C>>N)) return 0; int Sr,Sc,Gr,Gc; cin>>Sr>>Sc>>Gr>>Gc; --Sr; --Sc; --Gr; --Gc; vector<string> A(R); for(int i=0;i<R;i++) cin>>A[i]; if (Sr==Gr && Sc==Gc) { cout<<0<<"\n"; return 0; } int H = R - N + 1; // stamp rows int W = C - N + 1; // stamp cols // total stamps long long totalStamps = 1LL * H * W; // Node indexing: // cell nodes: 0 .. R*C-1 // stamp nodes: baseStamp = R*C .. R*C + totalStamps -1 int cells = R * C; long long baseStamp = cells; // dist array for all nodes (cells + stamps) // use int if fits; INF sentinel vector<int> dist; try { dist.assign(cells + (int)totalStamps, INF); } catch(...) { // fallback just in case (shouldn't happen within problem limits) return 0; } // DSU-like "find-next" arrays: // 1) For stamp rows: for each stamp-row (H rows), we keep array size W+1 // parentStampAll size = H * (W+1) // index base for row a: base = a*(W+1) vector<int> parentStamp; if (H>0 && W>0) parentStamp.assign((size_t)H * (W + 1), 0); auto stampBase = [&](int a){ return a * (W + 1); }; // init parentStamp for(int a=0;a<H;a++){ int base = stampBase(a); for(int b=0;b<=W;b++) parentStamp[base + b] = base + b; } // find-next for stamp (global array) function<int(int)> findStamp = [&](int x)->int{ int r = x; while(parentStamp[r] != r){ parentStamp[r] = parentStamp[parentStamp[r]]; r = parentStamp[r]; } return r; }; // 2) For cell rows: for each original grid row (R rows), keep array size C+1 // parentCellAll size = R * (C+1) vector<int> parentCell; parentCell.assign((size_t)R * (C + 1), 0); auto cellBase = [&](int row){ return row * (C + 1); }; for(int i=0;i<R;i++){ int base = cellBase(i); for(int j=0;j<=C;j++) parentCell[base + j] = base + j; } function<int(int)> findCell = [&](int x)->int{ int r = x; while(parentCell[r] != r){ parentCell[r] = parentCell[parentCell[r]]; r = parentCell[r]; } return r; }; auto cellId = [&](int r,int c){ return r * C + c; }; auto stampId = [&](int a,int b){ return (int)(baseStamp + a * 1LL * W + b); }; deque<int> dq; // initialize start cell int sId = cellId(Sr,Sc); dist[sId] = 0; dq.push_front(sId); // mark start as "removed" from cell DSU (so stamp won't iterate it again) { int base = cellBase(Sr); int pos = findCell(base + Sc); if(pos == base + Sc) parentCell[pos] = findCell(pos + 1); } // BFS const int dr[4] = {-1,1,0,0}; const int dc[4] = {0,0,-1,1}; while(!dq.empty()){ int u = dq.front(); dq.pop_front(); int du = dist[u]; if(u == cellId(Gr,Gc)){ cout<<du<<"\n"; return 0; } if(u < cells){ // cell node int r = u / C, c = u % C; // move to 4-neighbors if white (cost 0) for(int k=0;k<4;k++){ int nr = r + dr[k], nc = c + dc[k]; if(nr<0||nr>=R||nc<0||nc>=C) continue; if(A[nr][nc]=='.'){ int v = cellId(nr,nc); if(dist[v] > du){ dist[v] = du; dq.push_front(v); // remove from cell DSU if present int base = cellBase(nr); int pos = findCell(base + nc); if(pos == base + nc) parentCell[pos] = findCell(pos + 1); } } } // trigger stamps that cover this cell (cost 1) // a in [r-N+1, r] ∩ [0, H-1] // b in [c-N+1, c] ∩ [0, W-1] if(H>0 && W>0){ int a_low = max(0, r - N + 1); int a_high = min(r, R - N); int b_low = max(0, c - N + 1); int b_high = min(c, C - N); if(a_low <= a_high && b_low <= b_high){ for(int a = a_low; a <= a_high; ++a){ int base = stampBase(a); int pos = findStamp(base + b_low); while(true){ int col = pos - base; if(col > b_high) break; int s = stampId(a, col); if(dist[s] > du + 1){ dist[s] = du + 1; dq.push_back(s); } // remove this stamp column from DSU (so we won't process it again) parentStamp[pos] = findStamp(pos + 1); pos = findStamp(pos); } } } } } else { // stamp node int sid = u - cells; int a = sid / W; int b = sid % W; // stamp covers rows a..a+N-1, cols b..b+N-1 for(int i = a; i < a + N; ++i){ int base = cellBase(i); int pos = findCell(base + b); while(true){ int col = pos - base; if(col >= C) break; // sentinel if(col > b + N - 1) break; int v = cellId(i, col); if(dist[v] > dist[u]){ dist[v] = dist[u]; dq.push_front(v); } // remove this cell from DSU so future stamps skip it parentCell[pos] = findCell(pos + 1); pos = findCell(pos); } } } } // If BFS ends without reaching goal, print dist[goal] (might be INF) int ans = dist[cellId(Gr,Gc)]; if(ans==INF) cout<<-1<<"\n"; // problem statement guarantees it's possible by stamping enough times, but safe fallback else cout<<ans<<"\n"; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...