Stay Hungry,Stay Foolish!

P1002 [NOIP2002 普及组] 过河卒

P1002 [NOIP2002 普及组] 过河卒

https://www.luogu.com.cn/problem/P1002

 

思路

初始设置 0 行 0列的点 取值为1,表示有一条路径到达此目标点,  注意当遇到第一个障碍点, 停止赋值

然后对

1-n 行

1-m列

做dp计算 按照如下公式:

dp[x][y] = dp[x][y-1] + dp[x-1][y];

Code

https://www.luogu.com.cn/record/101844552

long long dp[21][21];
int n, m;
int bx, by;

bool is_blocked(int x, int y){
    if (x==bx && y==by){
        return true;
    }
    
    int steps[8][2] = {
            {1,2},
            {2,1},
            {2,-1},
            {1, -2},
            {-1, -2},
            {-2, -1},
            {-2, 1},
            {-1, 2},
        };
        
    for(int i=0; i<8; i++){
        int nx = bx + steps[i][0];
        int ny = by + steps[i][1];
        
        if (x==nx && y==ny){
            return true;
        }
    }
    
    return false;
}

int main()
{
    memset(dp, 0, sizeof(dp));
    
    cin >> n >> m;
    cin >> bx >> by;

    dp[0][0] = 1;

    for(int y=1; y<=m; y++){
        if (is_blocked(0, y)){
            break;
        }
        
        dp[0][y] = 1;
    }

    for(int x=1; x<=n; x++){
        if (is_blocked(x, 0)){
            break;
        }

        dp[x][0] = 1;
    }

    for(int x=1; x<=n; x++){
        for(int y=1; y<=m; y++){
//            cout << "x=" << x << "y=" << y <<endl;
            
            if (is_blocked(x, y)){
                continue;
            }
            
//            cout << "set" << endl;
            
            dp[x][y] = dp[x][y-1] + dp[x-1][y];
            
//            cout << "dp[x][y]=" << dp[x][y] << endl;
        }
    }

    cout << dp[n][m] << endl;

    return 0;
}

 

posted @ 2023-02-10 18:21  lightsong  阅读(31)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel