1. 程式人生 > >【2018/10/04】T2

【2018/10/04】T2

排隊

描述

在成都某中學有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;
}