最短路径的变相问题

 

拐弯

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值