其實模擬題常常用到環這個東西,我發覺挺多寬搜的題目也是,狀態來回轉移,最終成了環。ios
多說一點,最近作了很多寬搜的題(很簡單),發覺寬搜的題目有兩種特徵,一個是狀態數量有限,一個是求作完某件事的最少步驟(跟這道題不要緊)。數組
#include <cstdio> #include <cstring> #include <iostream> using namespace std; char g[20][20]; int vis[20][20]; int main() { // freopen("E_in.txt", "r", stdin); int n, m, e; while(scanf("%d%d%d", &n, &m, &e) && n + m + e) { memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; i++) scanf("%s", &g[i][1]); int x = 1, y = e, steps = 0; bool loop = false; for(;;) { // printf("%c", g[x][y]); if(x < 1 || x > n || y < 1 || y > m) break; if(!vis[x][y]) vis[x][y]++; else { loop = true; break; } switch(g[x][y]) { case 'N': x--; steps++; break; case 'S': x++; steps++; break; case 'W': y--; steps++; break; case 'E': y++; steps++; break; } } // printf("\n"); if(!loop) { printf("%d step(s) to exit\n", steps); } else { memset(vis, 0, sizeof(vis)); int d = 0; for(;;) { if(x < 1 || x > n || y < 1 || y > m) break; if(!vis[x][y]) vis[x][y]++; else break; switch(g[x][y]) { case 'N': x--; d++; break; case 'S': x++; d++; break; case 'W': y--; d++; break; case 'E': y++; d++; break; } } printf("%d step(s) before a loop of %d step(s)\n", steps-d, d); } } return 0; }
成環的狀況還要算成環以前走了幾步,因爲規模不大,我就清零了vis數組讓它又走了一遍環。。。連代碼都是複製粘貼的。還挺有效的,不怎麼用動腦子。oop