[NOIP題目] - 馬攔過河卒


題干

棋盤上AA點有一個過河卒,需要走到目標BB點。卒行走的規則:可以向下、或者向右。同時在棋盤上CC點有一個對方的馬,該馬所在的點和所有跳躍一步可達的點稱為對方馬的控制點。因此稱之為“馬攔過河卒”。

棋盤用坐標表示,A點(0, 0)、B點(n,m)(n, m為不超過20的整數),同樣馬的位置坐標是需要給出的。

現在要求你計算出卒從A點能夠到達B點的路徑的條數,假設馬的位置是固定不動的,並不是卒走一步馬走一步。

輸入輸出格式
輸入格式:
一行四個數據,分別表示B點坐標和馬的坐標。

輸出格式:
一個數據,表示所有的路徑條數。
輸入樣例 輸出樣例
6 6 3 3(注:空格分隔) 6

分析:
1、正常情況下,通過一個點路徑條數的算法
如果不考慮馬的因素,那么卒子線路中所經過的一個點,可以來自於兩個點,即此點正上方的點和左方的點,那么通過此點的路徑數量即為:正上方的點的路徑數量 + 左方的點的路徑數量(公式:f[n,m] = f[n, m -1] + f[n - 1, m])。
2、特殊情況1,馬的情況
3、最上邊界和最左邊界
如不考慮馬的情況,那么最上邊界和最左邊界上的點只是1。

代碼:

//
//  main.cpp
//  AdvancedPawn
//
//  Created on 2018/9/23.
//  Copyright © 2018. All rights reserved.
//

#include <iostream>
#include<stdio.h>
#include<string.h>



using namespace std;

int f[20][20];
int g[20][20];



int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    
    
    int i, j, n, m, x, y;
    memset(f, 0, sizeof(f)); //清空,數組元素起始值皆為0
    memset(g, 0, sizeof(g));
    scanf("%d %d %d %d", &n, &m, &x, &y); //輸入目標點B、馬的位置
    f[0][0] = 1; //思考一下為什么出發點的路徑數為1,而不是為0
    g[x][y] = 1; //自己偷偷舉個小栗子就知道啦^_^
    g[x - 1][y - 2] = 1; g[x - 1][y + 2] = 1; //馬的控制點
    g[x + 1][y + 2] = 1; g[x + 1][y - 2] = 1; //第一次做的時候
    g[x - 2][y - 1] = 1; g[x - 2][y + 1] = 1; //1和2傻傻沒看清楚
    g[x + 2][y - 1] = 1; g[x + 2][y + 1] = 1; //WA了N次,嗚嗚~
    for(i = 1; i <= n; i++){ //縱向邊界初始化(第一列)
        if(!g[i][0]){
            f[i][0] = 1; //不是馬的控制點,該點的路徑數設為1
        }
        else{            //否則在邊界上此點及之后的點路徑數為0
            break;       //思考一下為什么?
        }                //在邊界上還可以從哪里到該點?
    }                    //是不是不能了,因為可以來的路被馬“截斷”了
    for(i = 1; i <= m; i++){ //橫向邊界初始化(第一行)
        if(!g[0][i]){        //同上,不解釋
            f[0][i] = 1;
        }
        else{
            break;
        }
    }                        //一步步遞推
    for(i = 1; i <= n; i++){ //本題重要的代碼精華部分,模擬從起始點出發,每
        for(j = 1; j <= m; j++){ //一步到達的點的路徑數之和
            if(!g[i][j]) //如果不是馬的控制點,該點的路徑數為左邊+上邊點的路
                f[i][j] = f[i - 1][j] + f[i][j - 1]; //徑數
        }
    }
    printf("%d\n", f[n][m]); //輸出所有的路線和
    
    
    
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM