【2018/10/04】T2
阿新 • • 發佈:2018-12-13
排隊
描述
在成都某中學有m個男生與n個女生排隊,這個學校的女生比較古怪,從某個位置(包含這個位置)開始往前數,男生的數量超過了女生的數量,女生會感覺不安全,於是會大叫起來,為了構建和諧校園,安排隊伍時應該避免這樣的情況。請你計算出不會引發尖叫的排隊方案的概率。(排隊方案不同定義:當且僅當某個某個位置人不一樣,如男生A、男生B ,與男生B、男生A ,2個排列是不同方案)
輸入
第一行1個整數, 表示測試資料的組數。
每個資料 有兩個數 N,M(N個女生,M個男生)
輸出
對於每組資料,輸出一個實數(保留到小數點後 6 位)
樣例輸入
3 1 0 0 1 1 1
樣例輸出
1.000000 0.000000 0.500000
【 Hint】
第一組:只有一個女生,一種方案且可行
第二組:只有1個男生,一種方案且不行
第三組:兩種方案 女、男可行,男、女不可行,可行概率0.5
【資料規模】
30%的資料: (測試組數<=10),(0<=N,M<=1000).
100%的資料: (測試組數=9008 ), ( 0<=N,M<=20000 ).
分析
可以將原問題轉化一下,看成是在一個二維平面上行走,女生看成移動(1,0),男生看成移動(0,1),那麼到達(N,M)點且路線又不走到y=x 這條直線上方的路線總數就是答案,這個組合問題很經典,方案數為 C(M+N,M)-(M+N,M-1),所以可以知道答案就是
1-M/(N+1)
(以上摘自題解)
上面那個公式在推導的時候不要忘了最後還要再乘以m!*n!(因為A,B和B,A是兩種方案)
反正我是不可能想到這樣的轉化的,考場找規律:),這招是真的好用,只要願意花時間手推或者打表,就算不明白原理,八九十也是正確的
程式碼
#include<bits/stdc++.h> #define in read() using namespace std; int n; double a,b; inline int read(){ char ch;int f=1,res=0; while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1; while(ch>='0'&&ch<='9'){ res=(res<<3)+(res<<1)+ch-'0'; ch=getchar(); } return f==1?res:-res; } int main(){ n=in; while(n--){ scanf("%lf%lf",&a,&b); if(b==0) {printf("1.000000\n");continue;} if(a==0||a<b) {printf("0.000000\n");continue;} if(b==1) {printf("%.6f\n",a/(a+1.0));continue;} printf("%.6f\n",(a-b+1.0)/(a+1.0)); } return 0; }