题目中需要注意的地方:
1、转弯次数不能超过两次
2、只有起点位置和终点位置的棋子相同的时候,才进行dfs搜索,否则直接输出"NO"。如果不这样做,会超时!
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 typedef struct Node 6 { 7 int x1, y1; 8 int x2, y2; 9 }Node; 10 11 const int N = 1010; 12 const int dir[4][2] = { {-1,0}, {0,1}, {1,0}, {0,-1} }; 13 Node inquire[50]; //保存询问信息 14 bool visit[N][N]; //标记数组 15 int board[N][N]; //棋盘 16 int n, m, q; //行、列、询问次数 17 18 /* 输入(参数含义:行、列) */ 19 void input(void) 20 { 21 for (int i = 1; i <= n; ++i) 22 for (int j = 1; j <= m; ++j) 23 scanf("%d", &board[i][j]); 24 scanf("%d", &q); 25 for (int i = 0; i < q; ++i) 26 scanf("%d %d %d %d", &inquire[i].x1, &inquire[i].y1, &inquire[i].x2, &inquire[i].y2); 27 } 28 29 /* 判断是否越界 */ 30 inline bool inBoard(const int &row, const int &col) 31 { 32 return 1 <= row && row <= n && 1 <= col && col <= m; 33 } 34 35 /* dfs搜索(参数含义:行、列、第几次询问、当前的方向、当前的转弯次数) */ 36 bool dfs(const int &row, const int &col, const int &index, int direction ,int turnCount) 37 { 38 if (-1 != direction && 0 < board[row][col])// "1 != direction"的目的是防止起点的棋子进来 39 { 40 if (inquire[index].x2 == row && inquire[index].y2 == col) 41 return true; //碰到一个棋子,棋子能匹配,找到答案 42 else 43 return false; //碰到一个棋子,但是这个棋子不能匹配,因此需要退回去,不能继续向下搜索 44 } 45 46 for (int i = 0; i < 4; ++i) 47 { 48 int r = row + dir[i][0]; 49 int c = col + dir[i][1]; 50 if (true == inBoard(r, c) && false == visit[r][c]) 51 { 52 //记录之前的方向和转弯次数,用于后面回溯 53 int lastDirection = direction; 54 int lastTurnCount = turnCount; 55 56 //处理转弯 57 if (-1 == direction) //方向为-1表示刚开始搜索,还没有选方向 58 { 59 direction = i; 60 } 61 else if ( i != direction) //之前的方向与当前的方向不同,表示一次转弯 62 { 63 if (turnCount + 1 > 2) //转弯次数不能超过两次 64 continue; 65 direction = i; 66 turnCount++; 67 } 68 69 visit[r][c] = true; 70 71 //搜索 72 if (true == dfs(r, c, index, direction, turnCount)) 73 return true; 74 75 //回溯 76 visit[r][c] = false; 77 direction = lastDirection; 78 turnCount = lastTurnCount; 79 } 80 } 81 return false; 82 } 83 84 int main(void) 85 { 86 while (scanf("%d %d", &n, &m), n || m) 87 { 88 input(); 89 for (int i = 0; i < q; ++i) 90 { 91 if (board[inquire[i].x1][inquire[i].y1] != board[inquire[i].x2][inquire[i].y2]) 92 { 93 printf("NO "); 94 continue; 95 } 96 memset(visit, 0, sizeof(visit)); //搜索成功了,就不会回溯visit,所以每次开始搜索的时候需要清空visit 97 visit[inquire[i].x1][inquire[i].y1] = true; 98 if (true == dfs(inquire[i].x1, inquire[i].y1, i, -1, 0))//-1代表没有方向 99 printf("YES "); 100 else 101 printf("NO "); 102 } 103 } 104 return 0; 105 }