1. 程式人生 > >出題人的女裝(牛客練習賽38題B) (概率+分式運算)

出題人的女裝(牛客練習賽38題B) (概率+分式運算)

100% 比例 ostream 一個 兩個 int 根據 sync eps

鏈接:https://ac.nowcoder.com/acm/contest/358/B
來源:牛客網

出題人的女裝 時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 524288K,其他語言1048576K
64bit IO Format: %lld

題目描述

出題人早上起床就打算穿衣服,他有兩箱衣服,因為懶,他在這兩天只打算打開一個箱子. 兩個箱子中一個有n件衣服,其中有x件女裝,另一個有m件衣服,其中有y件女裝. 出題人在第一天隨機挑一個箱子後,接下來的兩天就會從此箱子中隨機找一件衣服穿.

又因為出題人懶而且很有錢,所以他穿完衣服後不會去洗,而是直接扔進垃圾桶,也不會放回原來的箱子.

已知出題人第1天穿了女裝,求他第二天依然穿女裝的概率

輸入描述:

第一行包含5個整數n,m,x,y,t

輸出描述:

若t=0,則在第一行輸出概率(四舍五入保留小數點後3位,概率為0輸出0.000,概率為100%輸出1.000)
若t=1,則在第一行輸出概率(最簡分數形式,概率為0輸出0/1,概率為100%輸出1/1)
示例1

輸入

復制
10 10 8 8 1

輸出

復制
7/9

備註:

2<=n,m<=10000
2<=x<=n且2<=y<=m
鏈接:https://ac.nowcoder.com/acm/contest/358/B
來源:牛客網
中文題意自行閱讀。
這個概率問題還是有點坑的,首先出題人第一天穿了是女裝,那麽他在用哪個箱子的概率不是1:1平等的,而是根據箱子中女裝概率的比例來的。
此處引用官方題解:
由於已知第一天穿了女裝,那麽選取兩個箱子的概率不是1:1了 Ans=P(兩次都取到女裝)/P(第一次取到女裝) P(兩次都取到女裝)= P(第一次取到女裝)= 因為分子分母都有 ,編程的時候可以忽略,減少代碼復雜度. 又由於和善的數據 範圍,只要long long暴力求分子分母然後化簡即可 這是一個叫貝葉斯定理的東西,有興趣的可以上網查一查
本人用直接用的封裝好的可以分式運算的結構體(很方便)。不會爆longlong,直接寫了。
x細節見我的ac代碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), ‘\0‘, sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"==  "<<x<<"  =="<<endl;
using namespace std;
//typedef __int128 ll;
typedef long long ll;
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll n,m,x,y,t;
ll gcd(ll a,ll b)
{
    if(b==0)
    {
        return a;
    }else
    {
        return gcd(b,a%b);
    }

}
ll ABS(ll x) {
    return x<0 ? -x : x;
}
struct F {
    ll num,den;// fenzi -> num  fenmu-> den
    F(ll num=0,ll den=1) {
        if(den<0) num=-num,den=-den;
        ll g = gcd(ABS(num),den);
        this->num = num/g;
        this->den = den/g;
    }
    F operator+(const F &o)const {
        return F(num*o.den + den*o.num, den*o.den);
    }
    F operator*(const F &o)const {
        return F(num*o.num , den*o.den);
    }
    F operator/(const F &o) const {
        return F(num*o.den,den*o.num);
    }
};
int main()
{
    cin>>n>>m>>x>>y>>t;
    if(t==0)
    {
        double ans=((x-1)*1.0*x/(n*(n-1))+(y*(y-1)*1.000/(m*(m-1))));
        ans=ans/(1.0*x/n+1.0*y/m);
        printf("%.3lf\n",ans);
    }else
    {
        F fz = (F(x,n)*F(x-1,n-1))  + (F(y,m)*F(y-1,m-1));
        F fm = F(x,n) + F(y,m);
        F  ans = fz/fm;
        cout<<(long long )ans.num<</<<(long long )ans.den<<endl;

    }
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch ==   || ch == \n);
    if (ch == -) {
        *p = -(getchar() - 0);
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 - ch + 0;
        }
    }
    else {
        *p = ch - 0;
        while ((ch = getchar()) >= 0 && ch <= 9) {
            *p = *p * 10 + ch - 0;
        }
    }
}



出題人的女裝(牛客練習賽38題B) (概率+分式運算)