第二個處理附帶轉折問題的題目
分析:
1.開始時就直接判斷 如果起點處和目標點處數字不同,或則起點或終點有一個是0,直接no。
2.因爲限定了最小轉向次數,所以採用bfs單向搜,hdu 1728與之及其類似
代碼:
/*
Note:
分析:
1.單方向BFS判斷轉折點,兩次轉折轉折次數爲3,從-1開始爲2
2.一開始時就開始判斷,如果起始點有一個是0或則起始點數字不同,則不需要受傷
*/
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
//#define test
const int maxn = 1000+2;
int G[maxn][maxn];
int n,m;
const int dx[]={-1,0,1,0}; // 上 右 下 左
const int dy[]={0,1,0,-1};
int vis[maxn][maxn];
bool ok;
struct point{
int x,y,cnt;
}s,e;
bool check(int x,int y){
return (x>=0 && x<n && y>=0 && y<m &&( G[x][y]==0 || ( x==e.x && y==e.y )))?true:false;
}
void bfs(){ //一個方向搜到底
queue<point> q;
s.cnt=-1;
q.push(s);
vis[s.x][s.y]=1;
int cnt;
while(!q.empty()){
point now = q.front(); q.pop();
for(int i=0;i<4;i++){
point t;
t.x=now.x+dx[i];
t.y=now.y+dy[i];
while( check(t.x,t.y) ){
if(!vis[t.x][t.y]){
vis[t.x][t.y]=1;
t.cnt=now.cnt+1;
q.push(t);
if(t.x==e.x && t.y==e.y && t.cnt<=2){ // 轉折次數不超過兩次相當於轉3次
ok=true;
return ;
}
}
t.x=t.x+dx[i], t.y=t.y+dy[i]; // 繼續一個方向搜
}
}
}
}
int main(){
#ifdef test
freopen("test.txt","r",stdin);
#endif
while(scanf("%d%d",&n,&m)!=EOF && n+m){
memset(G,0,sizeof(G));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&G[i][j]);
int q;
scanf("%d",&q);
for(int i=0;i<q;i++){
ok=false;
memset(vis,0,sizeof(vis));
scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
s.x-- , s.y-- , e.x-- , e.y--;
if((G[s.x][s.y]!=G[e.x][e.y]) || G[s.x][s.y]==0 || G[e.x][e.y]==0){
printf("NO\n");
continue;
}
bfs();
if(ok)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}