【中石油OJ-5151】 Jumping Haybales

题目描述

Farmer John's cows have grown lazy and he would like to get them back in shape! He  has decided that the best way to do this is by setting up haybales in the field and having  the cows jump from the northwest corner of the field to the southeast corner. The field  is an n×n square grid. Note that on a standard map, North is up, South is down, East is  right and West is left. 
A  cow  can  only  jump  straight east or  south, never  west  or  north,  or even  southeast.  They also have a limit k on how many cells they can jump. They can jump over haybales,  empty spaces, or any combination, even if there are no haybales in between, but they   cannot land on a haybale. Bessie wants to still be lazy and is interested in the minimum  number of jumps to reach the southeast corner of the map from the northwest corner. 

输入

Each input will consist of a single test case. Note that your program may be run multiple  times on different inputs. Each test case will begin with a line containing two integers n  and  k  (1  ≤  n,k  ≤  2,000),  where  n  is  the  size  of  one  side  of  the  square  grid,  and k is  Bessie’s  limit on the number of cells she can jump. Each of the next n lines will contain a  string with exactly n characters. Only the characters ‘#’ (a haybale) and ‘.’ (an empty  space) will appear. The northwest and southeast corners of the field are guaranteed to 
be empty. 

输出

Output a single integer, which is the minimum number of jumps Bessie needs to reach  the southeast corner from the northwest corner, or -1 if Bessie cannot make it.  

样例输入

4 2 
.### 
#... 
.#.. 

#.#.

样例输出

4

题意:一只羊要从左上跳到右下,最少要跳几步,#是草垛,不能降落,第一个数是方阵的大小,第二个数是羊每一步跳的最长距离。

思路,按照顺序,从第一排开始改,每次记录现在这一点所在的行改到了第几位,所在的列改到了第几位。

另:因为按照顺序改动,所以当改动某一个点时,这个点同行的点已经无法再由其上部分的点改动,就是说现在的值再按行改动之后就是他最好的值,所以如果当前的值就比所用更新的点的值+1要小,那么其后的点都应该由他来改,就是说在这一行里,现在所用的更新点已经没有用了。

代码:

#include<stdio.h>
#include<string.h>
char tu[2005][2005];
int hang[2005];
int hda[2005];
int lda[2005];
int lie[2005];
int bu[2005][2005];
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k)){
    for(int i=0; i<n; i++)
        scanf("%s",tu[i]);
    if(tu[0][0]=='#'||tu[n-1][n-1]=='#')
    {
        printf("-1\n");
        continue;
    }
    memset(hang,0,sizeof(hang));
    memset(lie,0,sizeof(lie));
    memset(bu,0,sizeof(bu));
    memset(lda,0x3f3f3f3f,sizeof(lda));
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(tu[i][j]=='.')
            {
                if(bu[i][j]==0&&(i!=0||j!=0))continue;
                if(lie[i]<=j)lie[i]=j+1;
                if(hang[j]<=i||lda[j]>bu[i][j]+1){hang[j]=i+1;}if(hang[j]<=i+k)lda[j]=bu[i][j]+1;
                for(; hang[j]<=i+k && hang[j]<n; hang[j]++)
                {
                    if(bu[hang[j]][j]==0||bu[hang[j]][j]>bu[i][j]+1)bu[hang[j]][j]=bu[i][j]+1;
                }
                for(; lie[i]<=j+k && lie[i]<n; lie[i]++)
                {
                    if(bu[i][lie[i]]==0||bu[i][lie[i]]>bu[i][j]+1)bu[i][lie[i]]=bu[i][j]+1;
                    else if(bu[i][lie[i]]!=0&&bu[i][lie[i]]<bu[i][j]+1&&tu[i][lie[i]]=='.'){lie[i]--;break;}
                }
            }
        }
    }
    if(bu[n-1][n-1]==0&&n!=1){printf("-1\n");continue;}
    printf("%d\n",bu[n-1][n-1]);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值