zoukankan      html  css  js  c++  java
  • [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!
    ";
        
        
        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
    ", f[n][m]); //输出所有的路线和
        
        
        
        return 0;
    }
  • 相关阅读:
    Linux eclipse 编译C++
    poj2774 Long Long Message(后缀数组or后缀自动机)
    ural 1297 Palindrome(Manacher模板题)
    bzoj 2049 Cave 洞穴勘测(LCT)
    codeforces 519E A and B and Lecture Rooms(LCA,倍增)
    hdu3830 (二分+LCA)
    codeforces 337D Book of Evil(dp)
    codeforces 22C System Administrator(构造水题)
    codeforces 144D Missile Silos(最短路)
    codeforces 505B Mr. Kitayuta's Colorful Graph(水题)
  • 原文地址:https://www.cnblogs.com/fphuang/p/9694326.html
Copyright © 2011-2022 走看看