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

标签: 思维 组合数 Lucas
40人阅读 评论(0) 收藏 举报
分类:

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;
}
查看评论

This is the first problem

This is the first problem Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述  As ...
  • guoqingshuang
  • guoqingshuang
  • 2015-11-16 18:57:17
  • 246

This is an A+B Problem

This is an A+B Problem Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 As usua...
  • guoqingshuang
  • guoqingshuang
  • 2015-11-16 18:58:32
  • 238

SDUTOJ 2613 This is an A+B Problem——大数模拟

 This is an A+B Problem Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ ...
  • u013014691
  • u013014691
  • 2014-06-30 13:32:53
  • 568

A+B Problem (sdut oj)

A+B Problem Time Limit: 1000MS Memory Limit: 65536KB Problem Description Calcul...
  • SwordsMan98
  • SwordsMan98
  • 2017-01-22 20:43:47
  • 200

POJ3062:Celebrity jeopardy

Description It's hard to construct a problem that's so easy that everyone will get it, yet still di...
  • libin56842
  • libin56842
  • 2013-03-10 22:02:42
  • 1600

Lucas大组合数模板

typedef long long ll;struct Lucas { ll n, m, p; ll qPow (ll a, ll k) { ll ans = 1; while (k) { if (k...
  • qq547276542
  • qq547276542
  • 2015-08-20 10:32:11
  • 1002

Algorithmics for Hard Problems

  • 2012年04月22日 22:16
  • 3.21MB
  • 下载

HDU 4403 A very hard Aoshu problem (暴力+状态压缩)

Problem Description Aoshu is very popular among primary school students. It is mathematics, but m...
  • h1021456873
  • h1021456873
  • 2016-03-23 16:21:19
  • 372

FZU 2020 组合 -- (大组合数取模 Lucas定理)

Problem 2020 组合 Accept: 892    Submit: 2120 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Pro...
  • qq_27717967
  • qq_27717967
  • 2016-05-24 21:49:06
  • 623

Lucas定理应用分析——大组合数取模

首先给出Lucas(卢卡斯)定理:     有非负整数A、B,和素数p,A、B写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]。 则组合数C(A,B)与C(a...
  • AC_Gibson
  • AC_Gibson
  • 2015-05-29 12:36:58
  • 917
    个人资料
    持之以恒
    等级:
    访问量: 2万+
    积分: 3116
    排名: 1万+
    文章存档
    最新评论