A - Arcade Game Gym - 100814A (概率思维题)

题目链接:https://cn.vjudge.net/contest/285964#problem/A

题目大意:每一次给你你一个数,然后对于每一次操作,可以将当前的数的每一位互换,如果互换后的数小于等于原来的数,那么停止操作,如果大于原来的数,则继续操作,到达当前这些数字能租成的最大的数的时候停止,然后问你能组成最大的数概率是多少?

具体思路:对于当前的数,我们先计算出这个比这个数大的有多少个,这个过程可以通过全排列的函数来进行计算。然后再计算一下当前的位数能构成的数的个数是多少,然后就开始求概率了。假设比当前的数大的有三个,那么概率计算就是 C(2,0)*(1/3)+C(2,1)*(1/3)*(1/3)+C(2,2)*(1/3)*(1/3)*(1/3).解释一下为什么是C(2,1),我们假设当前的关系是1>2>3,对于1,我们既可以通过2跳过去,还可以通过3跳过去,所以是C(2,1)。然后再开始化简式子(直接组合数会超时,,)对于上面的式子,我们把(1/3)提取出来,然后就变成了(1/3)*(1+2*(1/3)+(1/3)*(1/3)),然后就是(1/q)*(1+1/q)^(n-1).

AC代码:

 1 #include<iostream>
 2 #include<cmath>
 3 #include<stdio.h>
 4 #include<algorithm>
 5 using namespace std;
 6 # define ll long long
 7 const int maxn = 2e4+100;
 8 int f[maxn];
 9 int a[maxn];
10 int main(){
11   //  cout<<(1.0/6.0)*(1.0+1.0/6.0)<<endl;
12 int T;
13 f[1]=1;
14 for(int i=2;i<=10;i++){
15 f[i]=f[i-1]*i;
16 }
17 scanf("%d",&T);
18 while(T--){
19 int n;
20 scanf("%d",&n);
21 int num=0;
22 while(n){
23 a[++num]=n%10;
24 n/=10;
25 }
26 for(int i=1;i<=num/2;i++){
27 swap(a[i],a[num-i+1]);
28 }
29 int ans=0;
30 while(next_permutation(a+1,a+num+1)){
31 ans++;
32 }
33 if(ans==0){
34 printf("0.000000000\n");
35 continue;
36 }
37 double tot=1.0/(f[num]*1.0);
38 //cout<<f[num]<<endl;
39 double  d=1.0/(f[num]*1.0);
40 double tmp=1.0+d;
41 //cout<<tmp<<" "<<tot<<endl;
42 for(int i=1;i<ans;i++){
43         tot=tot*tmp;
44 }
45 printf("%.9lf\n",tot);
46 }
47 return 0;
48 }

 

posted @ 2019-03-08 14:43  Let_Life_Stop  阅读(279)  评论(0编辑  收藏  举报