14th SWJTUCPC Warming Up A chess Problem 【easy】【medium】【hard】【组合数 + lucas】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nobleman__/article/details/79974845

A chess Problem

描述

In chinese chess, “马” is an interesting piece, when it is at position(x,y), it can move to(x2,y1),(x2,y+1),(x1,y2),(x1,y+2),(x+1,y2),(x+1,y+2),(x+2,y1),(x+2,y+1),

Now the problem is, when a “马” is at position (x,y), how many ways does it have for he to move to (x0,y0).

To simplify this problem, when our “马” is at (x,y), it can only move to(x+1,y+2)or(x+2,y+1)

easy输入

The first line: the number of case T(≤T≤100)
Then T lines follow, each line contains four integers: x,y,x0,y0(0≤x,y,x0,y0≤8) - the position the “马” at and the position it want’s to go.

easy输出

For each case, out put an integer ans one line – the number of the ways to go from (x,y) to (x0,y0)

medium输入

The first line: the number of case T(≤T≤1000)
Then T lines follow, each line contains four integers: x,y,x0,y0(0≤x,y,x0,y0≤100000) - the position the “马” at and the position it want’s to go.

medium输出

For each case, out put an integer ans one line – the number of the ways to go from (x,y) to (x0,y0) mod 109+7

hard输入

The first line: the number of case T(≤T≤1000)
Then T lines follow, each line contains four integers: x,y,x0,y0(0≤x,y,x0,y0≤10000000) - the position the “马” at and the position it want’s to go.

hard输出

For each case, out put an integer ans one line – the number of the ways to go from (x,y) to (x0,y0) mod 104+7

样例输入1

3
0 0 3 3
0 0 6 6
3 3 6 6

样例输出1

2
6
2

提示

In the first example:

(0,0)−>(2,1)−>(3,3),(0,0)−>(1,2)−>(3,3)
In the second example:

(0,0)−>(2,1)−>(4,2)−>(5,4)−>(6,6),(0,0)−>(2,1)−>(3,3)−>(5,4)−>(6,6)
(0,0)−>(2,1)−>(3,3)−>(4,5)−>(6,6),(0,0)−>(1,2)−>(3,3)−>(5,4)−>(6,6)
(0,0)−>(1,2)−>(3,3)−>(4,5)−>(6,6),(0,0)−>(1,2)−>(2,4)−>(4,5)−>(6,6)
In the third example:

(3,3)−>(5,4)−>(6,6),(3,3)−>(4,5)−>(6,6)

题意:给你一个棋盘,难度不同,大小不同,给你起点和终点,问你有多少种方式可以从起点到达终点,你当前只能有两个位置可以走,假设你在(x,y),(x+2,y+1)(x+1,y+2)
分析:首先是easy,直接递归即可,范围很小, 主要说下medium和hard,我们可以通过平移使得起点始终为(0,0),所以我们只需考虑起点在(0,0) 即可,详见下图
这里写图片描述
根据上图,绿色区域为“马”能走到的坐标,首先可以确定的是,2,3,4,6,7,10,11,15,16,21只能够到达一次,比如5,可以从23坐标到达,而8,可以从45到达,12可以从78到达,现在应该可以找到规律了,如果把整体右旋135o,就变成熟悉的杨辉三角,比如8坐标能到达的方案即为“:C43,到这点了还不够,比如Cnk,我们怎么确定n和k呢,见下图

这里写图片描述

我们先将一点平移至(0,0),(x+y),然后将能到达的坐标延长后,发现(x+y) %3==0,先通过这一条件把一些点特判掉,然后还有延长线中到达不了的,特判掉即可
,我们找到此规律后就好办了,首先是medium,直接预处理出1e5的阶乘(取模后),然后有图找到相应的Cnk即可,hard里我们利用Lucas可以快速求大整数取模,详见代码

参考代码

// medium

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int maxn = 1e5 + 10;

const int MOD = 1e9 + 7;
typedef long long ll;

#define mod(x) ((x) % MOD)

ll qpow(ll a,ll b) {
    ll res = 1;
    while (b) {
        if(b & 1) {
            res = mod(res * a);
        }
        a = mod(a * a);
        b >>= 1;
    }
    return res;
}
ll x,y,xx,yy;
ll fac[maxn], rfac[maxn];


void init() {
    fac[0] = 1;
    for (int i = 1; i <= maxn; i++)
        fac[i] = mod(fac[i - 1] * i);
    rfac[maxn] = qpow(fac[maxn],MOD - 2);
    for (int i = maxn;i > 0; i--)
        rfac[i - 1] = mod(rfac[i] * i);
}
int main(){
    int T; cin>>T;
    init();
    while (T--) {
        cin>>x>>y>>xx>>yy;
        ll ex = xx - x;
        ll ey = yy - y;
        if(ex <= 0 || ey <= 0 || (ex + ey) % 3 != 0) {
            puts("0");
        } else {
            ll t = (ex + ey) / 3;
            ll bo = t;
            ll up = t + t;
            if(ey < bo || ey > up) {
                puts("0");
            } else {
                ll k = ey - t;
                ll n = t;
                cout<<mod(fac[n] * 1ll*mod(rfac[k]*1ll*rfac[n - k]))<<endl;
            }
        }
    }
    return 0;
}

参考代码

// hard
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int maxn = 1e5 + 7;

const int MOD = 1e4 + 7;
typedef long long ll;

#define mod(x) ((x) % MOD)

ll qpow(ll a,ll b) {
    ll res = 1;
    while (b) {
        if(b & 1) {
            res = mod(res * a);
        }
        a = mod(a * a);
        b >>= 1;
    }
    return res;
}

ll x,y,xx,yy;

ll C(ll nn, ll mm) {
    ll up = 1, down = 1;
    for (int i = nn - mm + 1; i <= nn; i++) up = mod(up * 1ll *i);
    for (int i = 1; i <= mm; i++) down = mod(down * 1ll *i);
    return mod(up * qpow(down, MOD - 2));
}

ll lucas(ll n, ll m) {
    if(m == 0) return 1;
    return mod(lucas(n / MOD, m / MOD) * 1ll * C(n % MOD,m % MOD));
}

int main(){
    int T; cin>>T;
    while (T--) {
        cin>>x>>y>>xx>>yy;
        ll ex = xx - x;
        ll ey = yy - y;
        if(ex <= 0 || ey <= 0 || (ex + ey) % 3 != 0) {
            puts("0");
        } else {
            ll t = (ex + ey) / 3;
            ll bo = t;
            ll up = t + t;
            if(ey < bo || ey > up) {
                puts("0");
            } else {

                ll k = ey - t;
                ll n = t;
                cout<<lucas(n,k)<<endl;
            }
        }
    }
    return 0;
}
阅读更多

A hard Aoshu Problem

02-10

DescriptionnnMath Olympiad is called “Aoshu” in China. Aoshu is very popular in elementary schools. Nowadays, Aoshu is getting more and more difficult. Here is a classic Aoshu problem: nnnABBDE __ ABCCC = BDBDEnnnIn the equation above, a letter stands for a digit(0 – 9), and different letters stands for different digits. After you fill the blank with '+', '-', '×' or '÷', and replace the letters with digits, you get an equation. nnHow to make the equation right? Here is a solution: nnn12245 + 12000 = 24245nnnIn that solution, A = 1, B = 2, C = 0, D = 4, E = 5, and '+' is filled in the blank. nnWhen I was a kid, finding a solution is OK. But now, my daughter’s teacher tells her to find all solutions. That’s terrible. I doubt whether her teacher really knows how many solutions are there. So please write a program for me to solve this kind of problems.nInputnnThe first line of the input is an integer T( T <= 20) indicating the number of test cases. nnEach test case is a line which is in the format below: nns1 s2 s3 nns1, s2 and s3 are all strings which are made up of capital letters. Those capital letters only include 'A','B','C','D' and 'E', so forget about 'F' to 'Z'. The length of s1,s2 or s3 is no more than 8. nnWhen you put a '=' between s2 and s3, and put a operator('+', '-', '×' or '÷'.) between s1 and s2, and replace every capital letter with a digit, you get a equation. nYou should figure out the number of solutions making the equation right. nnPlease note that same letters must be replaced by same digits, and different letters must be replaced by different digits. If a number in the equation is more than one digit, it must not have leading zero.nnOutputnnFor each test case, print an integer in a line. It represents the number of solutions.nnSample Inputn2nA A AnBCD BCD BnnnSample Outputn5n72n

没有更多推荐了,返回首页