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

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

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

提示

扫描二维码关注公众号,回复: 3097975 查看本文章


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;
    }
}

猜你喜欢

转载自blog.csdn.net/winter2121/article/details/82430508