P1002[过河卒]题解

· · 个人记录

前言

这道题不难,普及-的难度 但是我被坑了一下T_T

主要思路

这道题主要用了一个递推的思路,用一个二维数组来实现(我的二维数组名叫map) ,题目中说坐标是从(0,0)(n,m),为了避免数组越界,就将从(0,0)(n,m)变为从(1,1)(n + 1,m + 1) (就是坐标值增加1),再用for循环将map(0,0),map(0,1)...map(0, m)map(1,0),map(2,0)...map(n,0)设为0,再将马的坐标以及马能影响的坐标的值设为0。并且将map(1, 1)设为1,之后for循环开始递推,递推关系式为:

map(i,j) = map(i - 1,j) + map(i,j - 1)

遇到马的坐标以及马能影响的坐标时continue掉,最后输出map(n,m)即可! (加1后的n,m)

60分做法(部分分)

于是你信心十足地开始写代码!

#include <iostream>
#include <cstring>
using namespace std;
int map[30][30];
int main()
{
    memset(map,1,sizeof(map));
    int n,m,x,y;
    cin >> n >> m >> x >> y;
    x++; y++; n++; m++;
    map[x][y] = 0;
    map[x - 1][y - 2] = 0;
    map[x + 1][y - 2] = 0;
    map[x + 2][y - 1] = 0;
    map[x + 2][y + 1] = 0;
    map[x + 1][y + 2] = 0;
    map[x - 1][y + 2] = 0;
    map[x - 2][y - 1] = 0;
    map[x - 2][y + 1] = 0;
    for (int i = 0; i <= m; i++)
    {
        map[0][i] = 0;
    }
    for (int i = 0; i <= n; i++)
    {
        map[i][0] = 0;
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            if (map[i][j] == 0) continue;
            else if (i == 1 && j == 1) map[i][j] = 1;
            else map[i][j] = map[i - 1][j] + map[i][j - 1];
        }
    }
    cout << map[n][m] << endl;
    return 0;   
}

恭喜你!
.
.
.
.
.
你得到了60分! 但是我们要的是100分,是AC,并不是部分分!

为什么没AC?

我们来看我们的递推公式:

map(i,j) = map(i - 1,j) + map(i,j - 1)

根据递推公式,我们可知:(在没马的情况下)

map(2,2) = map(1,2) + map(2,1) = 1 + 1 = 2 = C_2^1 map(3,3) = map(2,3) + map(3,2) = 3 + 3 = 6 = C_4^2 map(4,4) = map(3,4) + map(4,3) = 10 + 10 = 20 = C_6^3 map(5,5) = map(4,5) + map(5,4) = 35 + 35 = 70 = C_8^4 ...

这个增长速度是非常快的!
我们看题目的限制条件

1≤n,m≤20 所以,**我们必须用$long long$**!!! # $AC$代码(含注释) 在最后,奉上我的$AC$代码 ```cpp #include <iostream> #include <cstring> //用memset using namespace std; long long map[30][30]; //必须用long long!!! int main() { memset(map,1,sizeof(map));//初始化 int n,m,x,y;//n,m为B点坐标,x,y为马的坐标 cin >> n >> m >> x >> y;//输入 x++; y++; n++; m++;//将坐标加1 //马的坐标以及马能影响的坐标的值的初始化 map[x][y] = 0; map[x - 1][y - 2] = 0; map[x + 1][y - 2] = 0; map[x + 2][y - 1] = 0; map[x + 2][y + 1] = 0; map[x + 1][y + 2] = 0; map[x - 1][y + 2] = 0; map[x - 2][y - 1] = 0; map[x - 2][y + 1] = 0; //初始化2 for (int i = 0; i <= m; i++) { map[0][i] = 0; } for (int i = 0; i <= n; i++) { map[i][0] = 0; } map[1][1] = 1;//初始化map[1][1] for (int i = 1; i <= n; i++)//遍历 { for (int j = 1; j <= m; j++) { if (map[i][j] == 0) continue;//对于马坐标的特殊处理 else map[i][j] = map[i - 1][j] + map[i][j - 1];//递推 } } cout << map[n][m] << endl;//输出 return 0; } ``` # 制作不易!!!