每次進行一次"徹底"的搜尋.所謂徹底的搜尋,就是一次性一條直線走過去,因為我們轉了一個彎之後無論走多遠都不會增加轉彎數;
| 0 |
1 |
2 |
3 |
| 0 |
0 |
0 |
0 |
| 0 |
1 |
2 |
1 |
| 0 |
0 |
0 |
0 |
比如上面這個表格,我們從 (4,3) 1出來後往下,轉彎數量為1(我們也記錄一次轉彎,最後判斷轉彎數不超過3而不是2)
到達(4,4) 再轉個彎往左走,我們可以一直走到(4,1) 都算2個彎.這就是 一次 "徹底" 的搜尋!
/* *HDU 1175 *fuqiang11 *BFS *2013/7/30 *關於轉彎次數,本來第一次 出去不計入方向,但是我們計入進去,所以最終判斷他不超過3個彎,而不是2個*/#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <cstdlib>using namespace std;#define maxn 1000+3int map[maxn][maxn];bool vis[maxn][maxn];int xx[] = {0,0,1,-1};int yy[] = {1,-1,0,0};int n,m;struct point{ int x; int y; int turn;};bool check(int x, int y){ if(x<1||y<1||x>n||y>m||vis[x][y]) return false; return true;}queue <point> q;int BFS(point st, point ed){ memset(vis,false,sizeof(vis)); while(!q.empty()) q.pop(); st.turn = 0; q.push(st); vis[st.x][st.y] = true; point a,b; while(!q.empty()) { a = q.front(); q.pop(); if(a.turn >= 3) //目前到達的點已經轉了3個彎了.再轉就超過了. return 0; for(int i = 0; i < 4; i++) { b.x = a.x + xx[i]; b.y = a.y + yy[i]; b.turn = a.turn + 1; while(check(b.x, b.y) && map[b.x][b.y]==0) { q.push(b); vis[b.x][b.y] = true; b.x += xx[i]; b.y += yy[i]; } if(check(b.x, b.y)) { if(b.x == ed.x && b.y == ed.y) //能到達終點 { if(b.turn <= 3) return 1; } } } } return 0;}int main(){#ifndef ONLINE_JUDGE freopen("in","r",stdin);#endif int q; point st,ed; while(scanf("%d%d",&n,&m)&&(n+m)) { for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d",&map[i][j]); scanf("%d",&q); while(q--) { scanf("%d%d%d%d",&st.x,&st.y,&ed.x,&ed.y); if(map[st.x][st.y] != map[ed.x][ed.y]) //連的塊不一樣,直接輸出 NO puts("NO"); else if(BFS(st,ed)) //找到 puts("YES"); else puts("NO"); } }}