广搜限制转弯次数
直线搜索当前位置的四个方向,把途中没有访问的点 turn 值 +1 入队。 说明:如果直线到达终点,则返回 true;如果四个方向都没有到达,则一定会转向,则退出队列中 turn 值 +1 的位置;首先判断当前 turn ,如果超限制,则一定不会再有位置可以到达终点(队列中的点都是不递减的);如果没有,继续直线搜索当前位置的四个方向。
#include <stdio.h> #include <string.h> #include <queue> using namespace std; #define M 102 struct node { int x,y,turn; node(int _x,int _y,int _turn) { x = _x; y = _y; turn = _turn; } }; char map[M][M]; int flag[M][M],move[4][2] = {-1,0,0,1,1,0,0,-1}; queue<node> q; int n,m,k; int judge(int x,int y) { if(x<1 || x>n || y<1 || y>m || map[x][y] == '*') return 0; return 1; } int bfs(int x1,int y1,int x2,int y2) { memset(flag,0,sizeof(flag)); while(!q.empty()) { q.pop(); } q.push(node(x1,y1,0)); flag[x1][y1] = 1; while(!q.empty()) { int turn = q.front().turn; if(turn > k) return 0; for(int i=0; i<4; i++) { int dx = q.front().x + move[i][0]; int dy = q.front().y + move[i][1]; while(judge(dx,dy)) { if(dx == x2 && dy == y2) return 1; if(!flag[dx][dy]) { flag[dx][dy] = 1; q.push(node(dx,dy,turn + 1)); } dx += move[i][0]; dy += move[i][1]; } } q.pop(); } return 0; } int main(int argc, char* argv[]) { #ifdef __MYLOCAL freopen("in.txt","r",stdin); #endif int t,x1,x2,y1,y2; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%s",map[i] + 1); } scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2); if(x1 == x2 && y1 == y2) { printf("yes "); continue; } if(bfs(x1,y1,x2,y2)) printf("yes "); else printf("no "); } return 0; }