2021年4月 上海月赛甲组 方格取数

方格路径

内存限制: 256 Mb

时间限制: 1000 ms

题目描述

在一个由 n×m个方格构成的图中,有 k 个方格是禁止进入的。请计算从左上角 (1,1)(1,1) 出发,每步朝右方或下方移动,不经过禁入的方格,最后到达右下角 (n,m) 的路径条数。由于答案很大,输出模 1,000,000,007 的余数。

输入格式

第一行:三个正整数表示n,m与 k。
第二行到第 n+1行:第 i+1行表示一个禁入方格的坐标 ( x i , y i ) (x_i,y_i) (xi,yi)。保证 ( x i , y i ) (x_i,y_i) (xi,yi) 不会等于 (1,1) 或 (n,m),也不会有一个坐标重复出现两次。

输出格式

单个自然数:表示路径数模 1,000,000,007 的余数。

数据范围

  • 对于 30% 的数据, 0 ≤ k ≤ 200 0\leq k\leq 200 0k200
  • 对于60% 的数据, 0 ≤ k ≤ 1500 0\leq k\leq 1500 0k1500
  • 对于 100% 的数据, 0 ≤ k ≤ 3000 0\leq k\leq 3000 0k3000
  • 1 ≤ n , m ≤ 1 0 5 1\leq n,m\leq 10^5 1n,m105

样例数据

输入:
100000 100000 4
50001 50001
50000 50000
50000 50001
50001 50000
输出:
999612315
输入:
2 2 2
2 1
1 2
输出:
0

递推解法一:递推

初看本题很像leecode 中63题。 不同路径 ,我们也可以使用Leecode中递推解法。 可以得到30分。 主要是本题得N和M的取值范围是100000.

算法的时间复杂度

O ( N × M ) O(N\times M) O(N×M) .

#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
typedef long long LL;

inline int read()
{
   
    int x = 0, f = 1;
    char s = getchar();
    while (s < '0' || s > '9')
    {
   
        if (s == '-')
            f = -f;
        s = getchar();
    }
    while (s >= '0' && s <= '9')
    {
   
        x = (x << 3) + (x << 1) + (s ^ 48);
        s = getchar();
    }
    return x * f;
}

class Solution
{
   
  public:
    int uniquePathsWithObstacles(vector<vector<int>> &o)
    {
   
        int n = o.size();
        if (n == 0)
            return 0;
        int m = o[0].size();
        vector<vector<int>> f(n, vector<int>(m));
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
            {
   
                //当o[i][j]==1 时候, 有石头挡住了。这点需要维持0.
                //我们要没有石头的地方开始转移。
                if (!o[i][j])
                {
   
                    if (!i && !j)
                        f[i][j] = 1;
                    else
                    {
   
                        if (i)
                            f[i][j] += f[i - 1][j];
                        if (j)
                            f[i][j] += f[i][j - 1];
                    }
                }
            }
        return f[n - 1][m - 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值