题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 参考思路:广度优先搜索。 源代码: #include <iostream> #include <algorithm> #include <cstdio> #include <queue> using namespace std; int array[1005][1005];//棋盘 int v[1005][1005][4]; //v[i][j][k]记录坐标(i, j)朝向为k的拐弯数,-1表示还未被搜索到,主要是为了剪枝优化 int n, m;//棋盘的长宽 //坐标(x, y)是否在棋盘中 inline bool in(int x, int y) { return x>=0 && x<n y>=0 && y<m; } struct node{ int x;//横坐标 int y;//纵坐标 int dir;//当前朝向,用0、1、2、3表示4个方向 int cnt;//已拐弯次数 }; //四个方向的位移 int dx[4] = {1, 0, -1, 0}; int dy[4] = {0, 1, 0, -1}; bool bfs(int x, int y, int x1, int y1) { if(array[x][y]==0 || array[x][y] != array[x1][y1]) return false; queue<node> qn; node t = {x, y, -1, 0}, tt; qn.push(t); int i, j, k; for(i=0; i!=n; i++) { for(j=0; j!=m; j++) { for(k=0; k!=4; k++) v[i][j][k] = -1;//初始化为还没被搜索到 } } while(!qn.empty()) { t = qn.front(); qn.pop(); if(t.x == x1 && t.y == y1) { return true; } else { for(i=0; i!=4; i++) { if(t.cnt == 2 && t.dir != i) {//拐弯次数将大于2次则继续 continue; } int xx = t.x + dx[i]; int yy = t.y + dy[i]; if(!in(xx, yy)) { continue; } if(xx == x1 && yy == y1) { return true; } if(array[xx][yy] != 0) { continue; } tt.x = xx; tt.y = yy; tt.dir = i; if(t.dir == -1 || t.dir == i) { tt.cnt = t.cnt; } else { tt.cnt = t.cnt + 1; } //如果未被搜索到或者拐弯次数比已经搜索到的小则入队 if(v[xx][yy][i] == -1 || v[xx][yy][i] > tt.cnt) { v[xx][yy][i] = tt.cnt; qn.push(tt); } } } } return false; } int main() { while(scanf("%d%d", &n, &m)==2) { if(n == 0) break; int i, j, k; for(i=0; i<n; i++) { for(j=0; j<m; j++) { scanf("%d", &array[i][j]); } } int x, y, x1, y1; int q; scanf("%d", &q); while(q--) { scanf("%d%d%d%d", &x, &y, &x1, &y1); if(bfs(--x, --y, --x1, --y1)) { printf("YES\n"); } else { printf("NO\n"); } } } return 0; }