hdu 4790 Just Random

Just Random

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1927    Accepted Submission(s): 530


Problem Description
  Coach Pang and Uncle Yang both love numbers. Every morning they play a game with number together. In each game the following will be done:
  1. Coach Pang randomly choose a integer x in [a, b] with equal probability.
  2. Uncle Yang randomly choose a integer y in [c, d] with equal probability.
  3. If (x + y) mod p = m, they will go out and have a nice day together.
  4. Otherwise, they will do homework that day.
  For given a, b, c, d, p and m, Coach Pang wants to know the probability that they will go out.
 

Input
  The first line of the input contains an integer T denoting the number of test cases.
  For each test case, there is one line containing six integers a, b, c, d, p and m(0 <= a <= b <= 10 9, 0 <=c <= d <= 10 9, 0 <= m < p <= 10 9).
 

Output
  For each test case output a single line "Case #x: y". x is the case number and y is a fraction with numerator and denominator separated by a slash ('/') as the probability that they will go out. The fraction should be presented in the simplest form (with the smallest denominator), but always with a denominator (even if it is the unit).
 

Sample Input
  
  
4 0 5 0 5 3 0 0 999999 0 999999 1000000 0 0 3 0 3 8 7 3 3 4 4 7 0
 

Sample Output
  
  
Case #1: 1/3 Case #2: 1/1000000 Case #3: 0/1 Case #4: 1/1
 

Source
 
题意:从a-b中选出x,从c-d中选出y,让你求取得(x+y)/p=m的概率,这里引用下kuangbin大神的图。
把[a,b] [c,d]所有可能组合的和写成下列形式。


a+c  a+c+1  a+c+2   ..................a+d


        a+c+1  a+c+2  a+c+3 ........a+d  a+d+1


                    a+c+2  a+c+3         a+d   a+d+1   a+d+2


                                ....................


                                ...................


                                b+c   b+c+1   ...............................................b+d;

上面大致形成一个斜的矩阵。

使用b+c  和 a+d两条竖线,就可以分成三部分。前后两部分个数是等差数列,中间个数是相等的。

#include <iostream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <algorithm>
#include<ctime>
#define esp 1e-6
#define LL long long
#define inf 0x0f0f0f0f
using namespace std;
__int64 gcd(__int64 da,__int64 xiao)
{
    if(da%xiao==0)
        return xiao;
    else
        return gcd(xiao,da%xiao);
}
int main()
{
    //FILE *fp1;
    //fp1=fopen("G:\\Users\\wu\\Desktop\\4790t.txt","w+");
    __int64 t,i,j,cas;
    __int64 a,b,c,d,p,m;
    __int64 fz,fm;
    scanf("%I64d",&t);
    for(cas=1;cas<=t;cas++)
    {
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m);
        __int64 s[10];
        __int64 st,ed;
        __int64 sum1,sum2,sum3;
        __int64 sm1,sm2,sm3;
        sum1=sum2=sum3=0;
        fm=(b-a+1)*(d-c+1);
        s[1]=a+c;
        s[2]=b+c;
        s[3]=a+d;
        s[4]=b+d;
        sort(s+1,s+1+4);
        if(s[1]%p==m)
            st=s[1];
        else
        {
            st=(s[1]/p)*p+m;
            if(st<s[1])
                st+=p;
        }
        if(s[2]%p==m)
            ed=s[2]-p;
        else
        {
            ed=(s[2]/p)*p+m;
            if(ed>s[2])
                ed-=p;
        }
        if(ed>=st)
        {
            st=st-(a+c)+1;
            ed=ed-(a+c)+1;
            sm1=(ed-st)/p+1;
            sum1=(st+ed)*sm1/2;
        }
        if(s[2]%p==m)
            st=s[2];
        else
        {
            st=(s[2]/p)*p+m;
            if(st<s[2])
                st+=p;
        }
        if(s[3]%p==m)
            ed=s[3]-p;
        else
        {
            ed=(s[3]/p)*p+m;
            if(ed>s[3])
                ed-=p;
        }
        if(ed>=st)
        {
            sum2=min((b-a+1),(d-c+1))*((ed-st)/p+1);
        }
        if(s[3]%p==m)
            st=s[3];
        else
        {
            st=(s[3]/p)*p+m;
            if(st<s[3])
                st+=p;
        }
        ed=s[4]/p*p+m;
        if(ed>s[4])
            ed-=p;
        if(ed>=st)
        {
            st=s[4]-st+1;
            ed=s[4]-ed+1;
            sm3=(st-ed)/p+1;
            sum3=(st+ed)*sm3/2;
        }
        fz=sum1+sum2+sum3;
       // printf("****%I64d %I64d %I64d\n",sum1,sum2,sum3);
        printf("Case #%I64d: %I64d/%I64d\n",cas,fz/gcd(fz,fm),fm/gcd(fz,fm));
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值