拐弯
memory limit: 65536KB time limit: 667MS
accept: 13 submit: 61
Description
N*N ( 1 <= N <= 100 ) 方格中, 'x' 表示不能走的格子, '.'表示可以走的格子。卡门很胖,故而不好转弯。现在要从A点走到B点,请问最少要转90度弯几次?
只可以上、下、左、右四个方向行走,并且不能走出这些格子之外。开始和结束时的方向可以任意。
Input
第一行一个整数: N ,下面N行,每行N个字符,只出现字符: '.' , 'x', 'A', 'B' ,表示上面所说的矩阵格子,每个字符后有一个空格(包括每一行的最后)。
2 <= N <= 100
Output
一个整数,最少转弯次数。如果不能到达,输出-1 。
Sample Input
3
. x A
. . .
B x .
Sample Output
2
思路:开始的想法是搜索最短路径,但是考虑到最短路径不一定就是拐弯数是最小的,又决定深搜,果断超时了!!
最后还是同学的提醒,这题可以是求最短路径的方法,只是变形为求最少的拐弯数,最短路径是以每步作为一个单位,这题要以每一个拐弯作为一个单位 。这样求得的拐弯数就是最少的拐弯数了。
代码:
#include<stdio.h>
char s[105][105];
int a[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct
{
int i,j;
int len;
}p[1000002];
int x1,y1,x2,y2,n;
int bfs()
{
int v,r,f,x,y,j,e,w;
r=f=0;
p[r].i=x1;
p[r].j=y1;
p[r].len=-1;
s[x1][y1]='x';
r++;
while(f<=r)
{
for(v=0;v<4;v++)
{
x=p[f].i+a[v][0];
y=p[f].j+a[v][1];
if(s[x][y]=='.')
{
s[x][y]='x';
p[r].i=x;
p[r].j=y;
p[r].len=p[f].len+1;
if(x==x2&&y==y2)
return p[r].len;
r++;
}
else
{
continue;
}
for(j=0;j<n;j++) //开始朝四个方向的一个方向一直搜下去,这跟最短路径的做法的区别,是以拐弯数来作为一个单位的
{
e=x+a[v][0];
w=y+a[v][1];
if(e<0||e>=n||w<0||w>=n)
break;
if(s[e][w]=='.')
{
s[e][w]='x';
p[r].i=e;
p[r].j=w;
p[r].len=p[f].len+1;
if(e==x2&&w==y2)
{
return p[r].len;
}
r++;
x=e;
y=w;
}
else
break;
}
}
f++;
}
return -1;
}
int main()
{
//freopen("a.txt","r",stdin);
int i,j;
scanf("%d",&n);
getchar();
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%c ",&s[i][j]);
if(s[i][j]=='A')
{
x1=i;
y1=j;
}
if(s[i][j]=='B')
{
s[i][j]='.';
x2=i;
y2=j;
}
}
}
printf("%d\n",bfs());
return 0;
}