Gym - 101617D

题目链接

转自


给出n*n的图,’.’能走,’#’不能走,k为最多能跳远的距离,每次只能往右或者往下走,求左上角到右下角最短需要多少步数。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 2000+5;
const int inf = 0x3f3f3f3f;

char a[N][N];
int row[N], col[N], d[N][N];
int n, k;
void init()
{
    for( int i = 0 ; i <= n ; i ++ ){
        row[i] = col[i] = 0;
        for( int j = 0 ; j <= n ; j ++ ){
            d[i][j] = inf;
        }
    }
}
int main()
{
    freopen("in.txt","r",stdin);
    while( scanf("%d%d", &n, &k) != EOF ){
        init();
        for( int i = 0 ; i < n ; i ++ ){
            scanf("%s",a[i]);
            //printf("%s\n",a[i]);
        }
        d[0][0] = 0;
        for( int i = 0 ; i < n ; i ++ ){
            for( int j = 0 ; j < n ; j ++ ){
                if( a[i][j] == '#' ) continue;
                ///维护最接近当前点d[i][j]的最小步数到达的列的位置下标
                for( ; col[i] < j ; col[i] ++ )
                    if( j-col[i] <= k && a[i][col[i]] == '.' )
                        break;
                d[i][j] = min( d[i][j], d[i][col[i]]+1 );
                ///同上
                for( ; row[j] < i ; row[j] ++ )
                    if( i-row[j] <= k && a[row[j]][j] == '.' )
                        break;
                d[i][j] = min( d[i][j], d[row[j]][j]+1 );
                ///维护最优值,或许一直能有最优值,也不需要下面这两行了
                ///max(row*col) = 2000*2000
                ///row[0~N] && col[0~N]无重复判断
                ///行列各维护一个数组 max(row*col) * 2
                if( d[i][j] <= d[i][col[i]] ) col[i] = j;
                if( d[i][j] <= d[row[j]][j] ) row[j] = i;
            }
        }
        if( d[n-1][n-1] == inf ) printf("-1\n");
        else printf("%d\n", d[n-1][n-1] );
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值