这题目跟之前的连连看还有hdu1072 都很像,就是路径受转弯次数的限制,这时vis[][]数组并非用来记录一个点是否已被访问过,而是记录经过该点的最少转弯次数,若经过该点存在更少的转弯次数的路径,则该点可以再次入队
看代码吧
#include<iostream> #include<queue> using namespace std; char map[101][101]; int n,m,T,ei,ej,dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int vis[101][101]; struct node { int x,y,di,turn; }; node f; void bfs() { queue<node> Q; Q.push(f); vis[f.x][f.y]=0; while(!Q.empty()) { node t=Q.front(),temp; Q.pop(); for(int k=0;k<4;k++) { int i=dir[k][0]+t.x; int j=dir[k][1]+t.y; if(i>n||i<1||j>m||j<1||map[i][j]=='*') continue; if(t.di!=k&&t.di!=-1) temp.turn=t.turn+1; else temp.turn=t.turn;//方向相同或刚出发 if(temp.turn>T) continue; if(i==ei&&j==ej) {cout<<"yes"<<endl; return ;} if(vis[i][j]>=temp.turn) { vis[i][j]=temp.turn; temp.x=i;temp.y=j;temp.di=k; Q.push(temp); } } } cout<<"no"<<endl; } int main() { int cas; cin>>cas; while(cas--) { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>map[i][j]; cin>>T>>f.y>>f.x>>ej>>ei;//把行跟列调换回来了,题目的那种叙述很不习惯 f.di=-1; f.turn=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) vis[i][j]=20;//也不需要初始化的很大,因为T本身最大也才10 bfs(); } return 0; }