P1002 过河卒 【递推、简单动规】

题目描述

棋盘上AA点有一个过河卒,需要走到目标BB点。卒行走的规则:可以向下、或者向右。同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,AA点(0, 0)(0,0)、BB点(n, m)(n,m)(nn, mm为不超过2020的整数),同样马的位置坐标是需要给出的。

现在要求你计算出卒从AA点能够到达BB点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入输出格式

输入格式:

一行四个数据,分别表示BB点坐标和马的坐标。

输出格式:

一个数据,表示所有的路径条数。

【题目提示了结果可能很大,疯狂暗示long long】

 

一开始想就20*20的格子,非常快的写了bfs,愉快地TLE。再次明白男人的直觉不可信,递推了一下式子。

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

很明眼的关系,就不费话了。

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;

bool box[22][22];
void into(int a, int b)
{
    for (int j = 0; j <= 20; j ++)
    {
        for (int k = 0; k <= 20; k ++)
        {
            box[j][k]= false;
        }
    }
    box[a][b]= true;
    if (a- 2>= 0)
    {
        if (b- 1>= 0)
        {
            box[a- 2][b- 1]= true;
        }
        if (b+ 1<= 20)
        {
            box[a- 2][b+ 1]= true;
        }
    }
    if (a+ 2<= 20)
    {
        if (b- 1>= 0)
        {
            box[a+ 2][b- 1]= true;
        }
        if (b+ 1<= 20)
        {
            box[a+ 2][b+ 1]= true;
        }
    }
    if (b- 2>= 0)
    {
        if (a- 1>= 0)
        {
            box[a- 1][b- 2]= true;
        }
        if (a+ 1<= 20)
        {
            box[a+ 1][b- 2]= true;
        }
    }
    if (b+ 2<= 20)
    {
        if (a- 1>= 0)
        {
            box[a- 1][b+ 2]= true;
        }
        if (a+ 1<= 20)
        {
            box[a+ 1][b+ 2]= true;
        }
    }
}
long long f[22][22];
int main()
{
    int x, y, a, b;
    while (cin >> x >> y >> a >> b)
    {
        into(a, b);
        for (int j = 0; j <= x; j ++)
        {
            for (int k = 0; k <= y; k ++)
            {
                f[j][k]= 0;
            }
        }
        f[0][0]= 1;
        for (int j = 0; j <= x; j ++)
        {
            for (int k = 0; k <= y; k ++)
            {
                if (! box[j][k])
                {
                    f[j+ 1][k]+= f[j][k];
                    f[j][k+ 1]+= f[j][k];
                }
            }
        }
//        for (int j = 0; j <= x; j ++)
//        {
//            for (int k = 0; k <= y; k ++)
//            {
//                printf("%4d", box[j][k]);
//            }
//            printf("\n");
//        }
//        printf("###############################\n");
//        for (int j = 0; j <= x; j ++)
//        {
//            for (int k = 0; k <= y; k ++)
//            {
//                printf("%4d", f[j][k]);
//            }
//            printf("\n");
//        }
        cout << f[x][y] << endl;
    }
    return 0;
}
View Code

bfs既然写了也丢着吧。

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;

bool box[22][22];
void into(int a, int b)
{
    box[a][b]= true;
    if (a- 2>= 0)
    {
        if (b- 1>= 0)
        {
            box[a- 2][b- 1]= true;
        }
        if (b+ 1<= 20)
        {
            box[a- 2][b+ 1]= true;
        }
    }
    if (a+ 2<= 20)
    {
        if (b- 1>= 0)
        {
            box[a+ 2][b- 1]= true;
        }
        if (b+ 1<= 20)
        {
            box[a+ 2][b+ 1]= true;
        }
    }
    if (b- 2>= 0)
    {
        if (a- 1>= 0)
        {
            box[a- 1][b- 2]= true;
        }
        if (a+ 1<= 20)
        {
            box[a+ 1][b- 2]= true;
        }
    }
    if (b+ 2<= 20)
    {
        if (a- 1>= 0)
        {
            box[a- 1][b+ 2]= true;
        }
        if (a+ 1<= 20)
        {
            box[a+ 1][b+ 2]= true;
        }
    }
}
bool Is_out_box (pair<int, int> p, int x, int y)
{
    if (p.first < 0 || p.first > x ) return true;
    if (p.second < 0 || p.second > y ) return true;
    return false;
}
queue<pair<int, int> >q;
int main()
{
    int x, y, a, b;
    while (cin >> x >> y >> a >> b)
    {
        for (int j = 0; j <= 20; j ++)
        {
            for (int k = 0; k <= 20; k ++)
            {
                box[j][k]= false;
            }
        }
        into(a, b);
        int cnt = 0;
        while (! q.empty()) q.pop();
        pair<int, int> p1 (0, 0);
        pair<int, int> p2, p3;
        q.push(p1);
        while (! q.empty())
        {
            p2= q.front();
            q.pop();
//            printf("%d -- %d\n", p2.first, p2.second);
            while (p2.first == x&& p2.second== y)
            {
                cnt ++;
                if (! q.empty() )p2= q.front(), q.pop();
                else break;
            }
            for (int c = 0; c < 2; c ++)
            {
                if (! c) p3.first= p2.first+ 1, p3.second= p2.second;
                else p3.first= p2.first, p3.second= p2.second+ 1;
                if (! box[p3.first][p3.second]&& ! Is_out_box(p3, x, y) ) q.push(p3);
            }
        }
        cout << cnt << endl;
    }
    return 0;
}
bfs

 

posted @ 2019-03-11 14:51  egoist的翻绳游戏  阅读(186)  评论(0编辑  收藏  举报