题目:http://acm.wust.edu.cn/problem.php?cid=1321&pid=4
分析:就是求起点到终点的最小拐弯数+1,用一个turn[x][y]维护每个点的最小拐弯数,如果扩展出的节点的拐弯数更小或等于,就把turn数组更新并把该点加进队列中去。
还有用i=0,1,2,3来代表四个方向,如果方向改变了说明转弯了,并用-1代表最初的方向,最初向哪边都不算转弯。
AC code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Node
{
int x,y;
int turn;
int dir;///方向
};
char s[80][80];
int turn[80][80];
int dx[4]= {1,-1,0,0};
int dy[4]= {0,0,-1,1};
int w,h;
int bfs(int sx,int sy,int ex,int ey)
{
queue<Node>que;
while(!que.empty()) que.pop();
memset(turn,0x3f3f3f3f,sizeof turn);
que.push({sx,sy,0,-1});
while(!que.empty())
{
Node cur=que.front();
que.pop();
if(cur.x==ex&&cur.y==ey)
return turn[cur.x][cur.y]+1;
for(int i=0; i<4; i++)
{
int tx=cur.x+dx[i];
int ty=cur.y+dy[i];
if(tx<0||ty<0||tx>h+1||ty>w+1) continue;///注意w,h别搞反了
if(s[tx][ty]=='X'&&(tx!=ex||ty!=ey)) continue;
int turns=cur.turn;
if(cur.dir!=i&&cur.dir!=-1)///如果方向改变
turns=cur.turn+1;
if(turn[tx][ty]>=turns)
{
que.push({tx,ty,turns,i});
turn[tx][ty]=turns;
}
}
}
return 0;
}
int main()
{
scanf("%d%d%*c",&w,&h);
for(int i=0; i<=h+1; i++)
for(int j=0; j<=w+1; j++)
s[i][j]=' ';
for(int i=1; i<=h; i++)
{
for(int j=1; j<=w; j++)
scanf("%c",&s[i][j]);
getchar();
}
int x1,y1,x2,y2;
while(scanf("%d%d%d%d",&x1,&y1,&x2,&y2)!=EOF&&(x1+x2+y1+y2))
{
printf("%d\n",bfs(y1,x1,y2,x2));///x,y别搞反了
}
return 0;
}