2018黑龙江省赛 A Path Plan(组合数学 美妙的计数原理)

7217: A Path Plan

时间限制: 1 Sec  内存限制: 128 MB
提交: 66  解决: 31
[提交] [状态] [讨论版] [命题人:admin]

题目描述

WNJXYK hates Destinys so that he does not want to meet him at any time. Luckily, their classrooms and dormitories are at different places. The only chance for them to meet each other is on their way to classrooms from dormitories. 
To simple this question, we can assume that the map of school is a normal rectangular 2D net. WNJXYK’s dormitory located at (0,y_1) and his classroom located at (x_1,0). Destinys’s dormitory located at (0,y_2) and his classroom is located at (x_2,0). On their way to classrooms, they can do two kinds of movement : (x,y)→(x,y-1) and (x,y)→(x+1,y). 
WNJXYK does not want to meet Destinys so that he thinks that it is not safe to let his path to classroom from dormitory has any intersect point with Destinys ‘s. And then he wonders how many different paths for WNJXYK and Destinys arriving their classrooms from dormitories safely.

输入

The input starts with one line contains exactly one positive integer T which is the number of test cases.
Each test case contains one line with four positive integers x1,x2,y1,y2 which has been explained above.

输出

For each test case, output one line containing “y” where y is the number of different paths modulo 10^9+7.

样例输入

3
1 2 1 2
2 3 2 4
4 9 3 13

样例输出

3
60
16886100

提示


T≤1000
x1<x2,y1<y2
0 < x1,x2,y1,y2≤100000
For Test Case 1, there are following three different ways.

来源/分类

2018黑龙江省赛 

[提交] [状态]

【题意】

如上图所示,在方格的左边缘给出两个点,下边缘给出两个点。两绿点之间连线,两红点之间连线,线路不能接触,并且由下边缘出发,仅能向左或向上走。问方案数

【分析】

若只考虑两红点连线(0,y),(x,0),一共要走y次竖边,x次横边,故方案数为 (y+x)! / ( x! * y! ),即C(x+y,x)

假设先不考虑线路相交,则方案数为 C( y1+x1,x1 ) * C( y2+x2,x2 )

考虑线路相交,不妨把下边缘的红点绿点互换,则这时的连线必然相交,连好这对相交的线路,马上把红点绿点换回来,会发现,此时的线路就是原问题线路相交的方案。所以线路相交方案数=下边缘红绿点互换后的总线路数,即C( x1+y2,x1 ) * C( x2+y1,x2 )

上面两方案数作差,即为不相交路线方案数。

【代码】

#include<bits/stdc++.h>
using namespace std;

const int mod=1e9+7;
const int MAX=2e5+5;
typedef long long ll;
ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
ll fac[MAX],INV[MAX];
ll C(int n,int m)
{
    if(n<m)return 0;
    if(m==0||n==m)return 1;
    return fac[n]*INV[m]%mod*INV[n-m]%mod;
}

int main()
{
    fac[0]=1;
    for(int i=1;i<MAX;i++)fac[i]=fac[i-1]*i%mod;
    INV[MAX-1]=inv(fac[MAX-1]);
    for(int i=MAX-2;i;i--)INV[i]=INV[i+1]*(i+1)%mod;
    ll x,y,u,v;
    int T;
    cin>>T;
    while(T--)
    {
        cin>>x>>u>>y>>v;
        ll ans=C(y+x,x)*C(v+u,u)%mod-C(v+x,x)*C(y+u,u)%mod;
        ans=(ans%mod+mod)%mod;
        cout<<ans<<endl;
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪的期许

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值