题目描述
到了难得的假期,小白班上组织大家去看电影。但由于假期里看电影的人太多,很难做到让全班看上同一场电影,最后大家在一个偏僻的小胡同里找到了一家电影院。但这家电影院分配座位的方式很特殊,具体方式如下:
-
电影院的座位共有K个,并被标号为1...K,每个人买完票后会被随机指定一个座位,具体来说是从1...K中等可能的随机选取一个正整数,设其为L。
-
如果编号L的座位是空位,则这个座位就分配给此人,否则将L加一,继续前面的步骤。
- 如果在第二步中不存在编号L的座位,则该人只能站着看电影,即所谓的站票。
小白班上共有N人(包括小白自己),作为数学爱好者,小白想知道全班都能够有座位的概率是多少。
输入输出格式
输入格式:
输入文件第一行有且只有一个正整数T,表示测试数据的组数。 第2~T+1行,每行两个正整数N,K,用单个空格隔开,其含义同题目描述。
输出格式:
输出文件共包含T行。第i行应包含两个用空格隔开的整数A,B,表示输入文件中的第i组数据的答案为A/B。(注意,这里要求将答案化为既约分数)
输入输出样例
输入样例#1:
3 1 1 2 1 2 2
输出样例#1:
1 1 0 1 3 4
范围
0<=n,k<=200
题解
组合数学加高精度
首先这是一个古典概型,概率等于合法的方案数除以总方案数。总方案数=K^N
合法方案数的计算:在最后面加一个座位,然后所有的座位连成一个环。现在那么总方案数等于(K+1)N,
每种环都算了(K+1)次,所以除以(K+1),最后抽调一个空白的座位来构造一个合法的方案,所以要乘(N−K+1)。
ans=(K+1)^(N-1)*(K-N+1)/K^N
高精度用十位一进
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 long long w=1e9; 7 long long c[20001],s1[20001],s2[20001],len1,len2; 8 void chen1(int k) 9 {int i; 10 memset(c,0,sizeof(c)); 11 for (i=1;i<=len1;i++) 12 { 13 c[i]+=s1[i]*k; 14 if (c[i]>=w) 15 { 16 c[i+1]+=c[i]/w; 17 c[i]%=w; 18 } 19 } 20 if (c[len1+1]) len1++; 21 while (c[len1]>=w) 22 { 23 c[len1+1]+=c[len1]/w; 24 c[len1]%=w; 25 len1++; 26 } 27 for (i=1;i<=len1;i++) 28 { 29 s1[i]=c[i]; 30 } 31 } 32 void chen2(int k) 33 {int i; 34 memset(c,0,sizeof(c)); 35 for (i=1;i<=len2;i++) 36 { 37 c[i]+=s2[i]*k; 38 if (c[i]>=w) 39 { 40 c[i+1]+=c[i]/w; 41 c[i]%=w; 42 } 43 } 44 if (c[len2+1]) len2++; 45 while (c[len2]>=w) 46 { 47 c[len2+1]+=c[len2]/w; 48 c[len2]%=w; 49 len2++; 50 } 51 for (i=1;i<=len2;i++) 52 { 53 s2[i]=c[i]; 54 } 55 } 56 void epow1(int x,int y) 57 {int i; 58 for (i=1;i<=y;i++) 59 chen1(x); 60 } 61 void epow2(int x,int y) 62 {int i; 63 for (i=1;i<=y;i++) 64 chen2(x); 65 } 66 void print1() 67 {int i,j; 68 printf("%lld",s1[len1]); 69 for (i=len1-1;i>=1;i--) 70 {int k=0; 71 long long x=s1[i]; 72 while (x) 73 {k++; 74 x/=10; 75 } 76 for (j=9;j>k;j--) 77 printf("0"); 78 if (s1[i]) 79 printf("%lld",s1[i]); 80 } 81 } 82 void print2() 83 {int i,j; 84 printf("%lld",s2[len2]); 85 for (i=len2-1;i>=1;i--) 86 {int k=0; 87 long long x=s2[i]; 88 while (x) 89 {k++; 90 x/=10; 91 } 92 for (j=9;j>k;j--) 93 printf("0"); 94 if (s2[i]) 95 printf("%lld",s2[i]); 96 } 97 } 98 long long gcd(long long a,long long b) 99 { 100 if (b==0) 101 { 102 return a; 103 } 104 long long r=gcd(b,a%b); 105 return r; 106 } 107 int main() 108 {int T,l,i,n,k; 109 //freopen("ans.out","w",stdout); 110 cin>>T; 111 for (l=1;l<=T;l++) 112 { 113 scanf("%d%d",&n,&k); 114 if (n>k) 115 { 116 cout<<0<<' '<<1<<endl; 117 continue; 118 } 119 memset(s1,0,sizeof(s1)); 120 memset(s2,0,sizeof(s2)); 121 s1[1]=1; 122 len1=1; 123 long long x=k-n+1; 124 for (i=1;i<=n;i++) 125 { 126 long long d=gcd(k,x); 127 x/=d; 128 chen1(k/d); 129 } 130 len2=1; 131 s2[1]=1; 132 epow2(k+1,n-1); 133 chen2(x); 134 print2(); 135 cout<<' '; 136 print1(); 137 cout<<endl; 138 } 139 }