#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <set> #include <map> #include <queue> using namespace std; /* freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); */ int maps[1001][1001],visit[1001][1001]; int n,m; int xx1,x2,yy1,y2; int t[4][2]={-1,0,1,0,0,-1,0,1}; struct xh { int x,y;//坐标 int step;//拐弯次数 int distant;//上一次走的方向,判断拐弯 }w,ww; bool panduan(int x,int y) { return x>=1&&x<=n&&y>=1&&y<=m; } void bfs() { queue<xh>q; q.push(w); while(!q.empty()) { ww=q.front(); q.pop(); if(ww.step>2) { continue; } for(int i=0;i<4;i++) { w=ww; w.x+=t[i][0]; w.y+=t[i][1]; w.distant=i; if(panduan(w.x,w.y)&&(maps[w.x][w.y]==0||w.x==x2&&w.y==y2)) { if(ww.distant!=520&&ww.distant!=w.distant) w.step++; if(w.step>2) continue; if(visit[w.x][w.y]>=w.step)//这个地方一定是大于等于,因为可能回搜 { visit[w.x][w.y]=w.step; q.push(w); } if(w.x==x2&&w.y==y2) { printf("YES\n"); return ; } } } } printf("NO\n"); return ; } int main() { int i,j,k; while(cin>>n>>m&&n+m) { for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&maps[i][j]); scanf("%d",&k); while(k--) { scanf("%d%d%d%d",&xx1,&yy1,&x2,&y2); if(maps[xx1][yy1]!=maps[x2][y2]||maps[xx1][yy1]==0)//不是同一个数或为0,直接输出NO { printf("NO\n"); continue; } memset(visit,1,sizeof(visit));//将visit初始化大一些 w.x=xx1; w.y=yy1; w.step=0; w.distant=520;//初始化方向 visit[w.x][w.y]=0; bfs(); } } return 520; }
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1175
广搜(bfs)
主要问题是记录拐弯次数,比较上一次和这一次的方向,方向相同拐弯次数不变,不同+1。
广搜有重复,所以用到一个技巧,将visit初始化大一些,当前拐弯次数小于visit时,才将当前拐弯次数赋值给visit,然后push。
题目代码如下:很清晰
作者:ilovexiaohao 发表于2013-4-13 17:22:36 原文链接
阅读:31 评论:0 查看评论