cf1607 F. Robot on the Board 2(搜尋)
阿新 • • 發佈:2021-11-13
https://codeforces.com/contest/1607/problem/F
題意:
在一個字元矩陣上走,U/D/L/R
表示站在某個字元上時,下一步必須按指定的方向走。不能越界或者走到已經走過的點上。問選哪個點為起點能走的步數最多
思路:
應該算dfs,但是據說c++17
遞迴會爆棧,得放棄遞迴或者用c++14
從每個點出發能走的路徑是唯一確定的。每一次選一個沒確定答案的點開始搜尋,開path
陣列記錄這次搜尋經過的點。搜尋過程中,如果遇到已經確定答案的點或者到達邊界,就回溯更新path
上的所有點的答案;若遇到這次搜尋曾走過的點,說明這次搜尋遇到了一個環,就回溯找環的起點,並把環上所有點的距離更新為環的長度
#include <iostream> using namespace std; const signed N = 2010; char G[N][N]; int cnt[N][N], pathx[N * N], pathy[N * N]; int n, m; void sou(int x, int y) { int len = 0, done = 0; while(x >= 1 && x <= n && y >= 1 && y <= m) { if(cnt[x][y] == -1) //這條路上有環 { int cirbegin = len; while(pathx[cirbegin] != x || pathy[cirbegin] != y) cirbegin--; //往回找環的起點 for(int i = cirbegin; i <= len; i++) //更新環上所有點的答案 cnt[pathx[i]][pathy[i]] = len - cirbegin + 1; done = len - cirbegin + 1; len = cirbegin - 1; break; } if(cnt[x][y]) //到達已經有答案的點 { done = cnt[x][y]; break; } pathx[++len] = x, pathy[len] = y; cnt[x][y] = -1; //標記這次搜尋中走過該點 switch(G[x][y]) { case 'L': y--; break; case 'R': y++; break; case 'D': x++; break; case 'U': x--; break; } } for(int i = 1; i <= len; i++) //回溯更新路徑上所有點的答案 cnt[pathx[len+1-i]][pathy[len+1-i]] = i + done; } signed main() { int T; cin >> T; while(T--) { cin >> n >> m; for(int i = 1; i <= n; i++) cin >> G[i] + 1; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) cnt[i][j] = 0; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) if(!cnt[i][j]) sou(i, j); int xx = 0, yy = 0; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) if(cnt[xx][yy] < cnt[i][j]) xx = i, yy = j; cout << xx << ' ' << yy << ' ' << cnt[xx][yy] << '\n'; } return 0; }