版权声明:虽然我只是个小蒟蒻但转载也请注明出处哦 https://blog.csdn.net/weixin_42557561/article/details/82937471
排队
描述
在成都某中学有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
扫描二维码关注公众号,回复:
3432853 查看本文章
【 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;
}