• 【9307】&【a303】过河卒(NOIP2002)


    Time Limit: 10 second
    Memory Limit: 2 MB

    问题描述
    如图,A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。
    同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为方马的控制点。例如上图C点上的马可以控制9个点(图中的P1,P2...P8和C)。卒不能通过对方的控制点。
    棋盘用坐标表示,A点(0,0)、B点(n, m)(n,m为不超过20的整数,并由键盘输入),同样马 的位置坐标是需要给出的(约定:C≠A,同时C≠B)。现在要求你计算出卒从A点能够到达B点的路 径的条数。

    Input

    B点的坐标(n,m)以及对方马的坐标(X,Y) {不用判错}

    Output

    一个整数(路径的条数)。

    Sample Input

    8 6 0 4
    
    
    

    Sample Output

    1617
    

    【题解】

    这是个递推题,每个卒只能从左上和右上角到达。

    设a[i][j]表示卒到达(i,j)这个点的方案数,a[i][j] = a[i][j-1] + a[i-1][j];

    首先用一个二维的bool型数组bo[21][21]来表示各个点是否为马所占据。一开始所有的点都置为true.然后把马所在的位置和马跳一步能到的位置置为false。表示这些点不能放卒。接下来是边界,首先for i = 1;i <= xB;i++ 如果遇到的bo[i][0]==true则这个点a[i][0] = 1,如果为false则直接停止。不再往下置1;上边界也是一样的规律。

    然后从(1,1)一直递推到XB,YB就可以了,用普通的int不能完整存下数据,要用double型来存。

    【代码】

    #include <cstdio>
    
    int xb,yb,xm,ym;
    double a[21][21];
    bool bo[21][21];
    
    void input_data()
    {
        scanf("%d %d %d %d",&xb,&yb,&xm,&ym);
        for (int i = 0;i <= xb;i++)
            for (int j = 0;j <= yb;j++) //一开始 所有的位置都能放
                bo[i][j] = true;
        for (int i = 0;i <= xb;i++) //到达所有点的方案数,都置为0.
            for (int j = 0;j <= yb;j++)
                a[i][j] = 0;
        int x0,y0; //x0 y0是马能控制的点
    
        bo[xm][ym] = false; //这是马所在的点
    
        x0 = xm -1;y0 = ym-2; //接下来的多行都是用来标记马跳一步能到达的点。
        if ( (x0 >= 0) && (y0 >=0))
            bo[x0][y0] = false;
    
        x0 = xm -2;y0 = ym -1;
        if ( (x0 >= 0) && (y0 >=0))
            bo[x0][y0] = false;
    
        x0 = xm -2;y0 = ym+1;
        if ( (x0 >= 0) && (y0 <=yb))
            bo[x0][y0] = false;
    
        x0 = xm - 1;y0 = ym +2;
        if ( (x0 >= 0) && (y0 <=yb))
            bo[x0][y0] = false;
    
        x0 = xm +1;y0 = ym +2;
        if ( ( x0 <= xb) && (y0 <= yb))
            bo[x0][y0] = false;
    
        x0 = xm +2;y0 = ym+1;
        if ( (x0 <= xb) && (y0 <= yb))
            bo[x0][y0] = false;
    
        x0 = xm+1;y0 = ym-2;
        if ( (x0 <= xb) && (y0 >=0))
            bo[x0][y0] = false;
    
        x0 = xm +2;y0 = ym-1;
        if ( (x0 <= xb) && (y0 >=0))
            bo[x0][y0] = false;
    }
    
    void get_ans()
    {
        for (int i = 0;i <= xb;i++) //接下来两个for循环 处理边界问题。
            if (bo[i][0])
                a[i][0] = 1;
                    else
                        break;
        for (int i = 0;i <= yb;i++)
            if (bo[0][i])
                a[0][i] = 1;
                    else
                        break;
        for (int i = 1;i <= xb;i++) //进行递推
            for (int j = 1;j <= yb;j++)
                if (bo[i][j])
                    a[i][j] = a[i-1][j] + a[i][j-1];
    }
    
    void output_ans()
    {
        printf("%0.lf
    ",a[xb][yb]); //%0.lf用来输出double,且不保留小数。
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        input_data();
        get_ans();
        output_ans();
        return 0;
    }
    


  • 相关阅读:
    学习
    素数环
    数独
    nyoj迷宫寻宝(一)
    Django H1 高级教程:如何编写可重用的应用
    Django L6 编写你的第一个Django应用
    Django L5 编写你的第一个Django应用
    Django L4 编写你的第一个Django应用
    Django L3 编写你的第一个Django应用
    Django L2 编写你的第一个Django应用
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632430.html
Copyright © 2020-2023  润新知