题目:http://acm.hdu.edu.cn/showproblem.php?pid=1099
英文水平太差了,题目实在是不知道是什么意思,然后看了其他高手写的思路,才看明白。
题意,收集n张彩票(1~n)平均需要抽几次彩票。这相当于是概率的问题。
假设n=3;
收集1 2 3 有如下过程
第一次抽到的概率为 1 抽到平均需要1次
第二次抽到的概率为2/3 抽到平均需要2/3次
第三词抽到的概率为1/3 抽到的平均需要3/1次
so 平均需要 1+2/3+3/1=5.5次
1 #include <stdio.h> 2 #include <iostream> 3 #include <string> 4 #include <cstring> 5 using namespace std; 6 7 __int64 gcd(__int64 a, __int64 b)//求最小公倍数 8 { 9 if(b == 0) return a; 10 return gcd(b, a % b); 11 } 12 13 __int64 getlen(__int64 x)//求位数 14 { 15 __int64 cnt = 0; 16 while(x) 17 { 18 cnt++; 19 x /= 10; 20 } 21 return cnt; 22 } 23 24 int main() 25 { 26 __int64 n; 27 while(scanf("%I64d", &n) != EOF) 28 { 29 __int64 fm = 1, fz = n, temp;//fz分子 fm分母; 30 for(__int64 i = 2; i <= n; i++) 31 { 32 fz = fz * i + fm * n;//分子 分母交叉相乘 eg:3/1+3/2=(/2*3+1*3)/1*2=9/2; 33 fm *= i; 34 temp = gcd(fz, fm); 35 fz /= temp; 36 fm /= temp; 37 } 38 __int64 a = fz / fm; 39 if(fz % fm == 0) 40 { 41 printf("%I64d\n", a); 42 continue; 43 } 44 fz = fz - fm * a; 45 //计算位数 46 __int64 len_fm = getlen(fm);//经过上面的化简必然是分子小于分母 47 // __int64 len_fz = getlen(fz); 48 __int64 len_a = getlen(a); 49 // __int64 maxx = max(len_fm, len_fz); 50 for(__int64 i = 0; i < len_a + 1; i++) 51 putchar(' '); 52 printf("%I64d\n", fz); 53 printf("%I64d ", a); 54 for(__int64 i = 0; i < len_fm; i++) 55 putchar('-'); 56 puts(""); 57 for(__int64 i = 0; i < len_a + 1; i++) 58 putchar(' '); 59 printf("%I64d\n", fm); 60 } 61 return 0; 62 }