HDU 4762 Cut the Cake (2013长春网络赛1004题,公式题)

Cut the Cake

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 300    Accepted Submission(s): 135

Problem Description MMM got a big big big cake, and invited all her M friends to eat the cake together. Surprisingly one of her friends HZ took some (N) strawberries which MMM likes very much to decorate the cake (of course they also eat strawberries, not just for decoration). HZ is in charge of the decoration, and he thinks that it’s not a big deal that he put the strawberries on the cake randomly one by one. After that, MMM would cut the cake into M pieces of sector with equal size and shape (the last one came to the party will have no cake to eat), and choose one piece first. MMM wants to know the probability that she can get all N strawberries, can you help her? As the cake is so big, all strawberries on it could be treat as points.  

 

Input First line is the integer T, which means there are T cases.

For each case, two integers M, N indicate the number of her friends and the number of strawberry.

(2 < M, N <= 20, T <= 400)  

 

Output As the probability could be very small, you should output the probability in the form of a fraction in lowest terms. For each case, output the probability in a single line. Please see the sample for more details.  

 

Sample Input 2 3 3 3 4  

 

Sample Output 1/3 4/27  

 

Source
2013 ACM/ICPC Asia Regional Changchun Online  

 

Recommend liuyiding  

 

题目意思很容易看懂。

 

公式就是 n / (m^(n-1))

这个结果可以积分求得。

 

枚举两个点,位于两边,就是P(n,2) = n*(n-1)

然后两个点形成的角度范围在 0~1/m之间。剩下n-2个点放的概率就是 x^(n-2)

 

所以积分 从0~1/m    x^(n-2) 对x进行积分。积分结果乘上n*(n-1)

 

要用高精度。

一种是C++ 完全高精度模板,积攒到最后一场网络赛终于用上了,一用就是两题,哈哈。

 

但是还是JAVA写起来爽,简单

 

 

C++版:

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013/9/28 星期六 12:54:45
  4 File Name     :2013长春网络赛\1004.cpp
  5 ************************************************ */
  6 
  7 #pragma comment(linker, "/STACK:1024000000,1024000000")
  8 #include <stdio.h>
  9 #include <string.h>
 10 #include <iostream>
 11 #include <algorithm>
 12 #include <vector>
 13 #include <queue>
 14 #include <set>
 15 #include <map>
 16 #include <string>
 17 #include <math.h>
 18 #include <stdlib.h>
 19 #include <time.h>
 20 using namespace std;
 21 /*
 22  * 完全大数模板
 23  * 输出cin>>a
 24  * 输出a.print();
 25  * 注意这个输入不能自动去掉前导0的,可以先读入到char数组,去掉前导0,再用构造函数。
 26  */
 27 #define MAXN 9999
 28 #define MAXSIZE 1010
 29 #define DLEN 4
 30 
 31 class BigNum
 32 {
 33 private:
 34     int a[500];  //可以控制大数的位数
 35     int len;
 36 public:
 37     BigNum(){len=1;memset(a,0,sizeof(a));}  //构造函数
 38     BigNum(const int);     //将一个int类型的变量转化成大数
 39     BigNum(const char*);   //将一个字符串类型的变量转化为大数
 40     BigNum(const BigNum &); //拷贝构造函数
 41     BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算
 42     friend istream& operator>>(istream&,BigNum&); //重载输入运算符
 43     friend ostream& operator<<(ostream&,BigNum&); //重载输出运算符
 44 
 45     BigNum operator+(const BigNum &)const;  //重载加法运算符,两个大数之间的相加运算
 46     BigNum operator-(const BigNum &)const;  //重载减法运算符,两个大数之间的相减运算
 47     BigNum operator*(const BigNum &)const;  //重载乘法运算符,两个大数之间的相乘运算
 48     BigNum operator/(const int &)const;     //重载除法运算符,大数对一个整数进行相除运算
 49 
 50     BigNum operator^(const int &)const;     //大数的n次方运算
 51     int operator%(const int &)const;        //大数对一个int类型的变量进行取模运算
 52     bool operator>(const BigNum &T)const;   //大数和另一个大数的大小比较
 53     bool operator>(const int &t)const;      //大数和一个int类型的变量的大小比较
 54 
 55     void print();        //输出大数
 56 };
 57 BigNum::BigNum(const int b)   //将一个int类型的变量转化为大数
 58 {
 59     int c,d=b;
 60     len=0;
 61     memset(a,0,sizeof(a));
 62     while(d>MAXN)
 63     {
 64         c=d-(d/(MAXN+1))*(MAXN+1);
 65         d=d/(MAXN+1);
 66         a[len++]=c;
 67     }
 68     a[len++]=d;
 69 }
 70 BigNum::BigNum(const char *s)  //将一个字符串类型的变量转化为大数
 71 {
 72     int t,k,index,L,i;
 73     memset(a,0,sizeof(a));
 74     L=strlen(s);
 75     len=L/DLEN;
 76     if(L%DLEN)len++;
 77     index=0;
 78     for(i=L-1;i>=0;i-=DLEN)
 79     {
 80         t=0;
 81         k=i-DLEN+1;
 82         if(k<0)k=0;
 83         for(int j=k;j<=i;j++)
 84             t=t*10+s[j]-'0';
 85         a[index++]=t;
 86     }
 87 }
 88 BigNum::BigNum(const BigNum &T):len(T.len)  //拷贝构造函数
 89 {
 90     int i;
 91     memset(a,0,sizeof(a));
 92     for(i=0;i<len;i++)
 93         a[i]=T.a[i];
 94 }
 95 BigNum & BigNum::operator=(const BigNum &n)  //重载赋值运算符,大数之间赋值运算
 96 {
 97     int i;
 98     len=n.len;
 99     memset(a,0,sizeof(a));
100     for(i=0;i<len;i++)
101         a[i]=n.a[i];
102     return *this;
103 }
104 istream& operator>>(istream &in,BigNum &b)
105 {
106     char ch[MAXSIZE*4];
107     int i=-1;
108     in>>ch;
109     int L=strlen(ch);
110     int count=0,sum=0;
111     for(i=L-1;i>=0;)
112     {
113         sum=0;
114         int t=1;
115         for(int j=0;j<4&&i>=0;j++,i--,t*=10)
116         {
117             sum+=(ch[i]-'0')*t;
118         }
119         b.a[count]=sum;
120         count++;
121     }
122     b.len=count++;
123     return in;
124 }
125 ostream& operator<<(ostream& out,BigNum& b)  //重载输出运算符
126 {
127     int i;
128     cout<<b.a[b.len-1];
129     for(i=b.len-2;i>=0;i--)
130     {
131         printf("%04d",b.a[i]);
132     }
133     return out;
134 }
135 BigNum BigNum::operator+(const BigNum &T)const   //两个大数之间的相加运算
136 {
137     BigNum t(*this);
138     int i,big;
139     big=T.len>len?T.len:len;
140     for(i=0;i<big;i++)
141     {
142         t.a[i]+=T.a[i];
143         if(t.a[i]>MAXN)
144         {
145             t.a[i+1]++;
146             t.a[i]-=MAXN+1;
147         }
148     }
149     if(t.a[big]!=0)
150        t.len=big+1;
151     else t.len=big;
152     return t;
153 }
154 BigNum BigNum::operator-(const BigNum &T)const  //两个大数之间的相减运算
155 {
156     int i,j,big;
157     bool flag;
158     BigNum t1,t2;
159     if(*this>T)
160     {
161         t1=*this;
162         t2=T;
163         flag=0;
164     }
165     else
166     {
167         t1=T;
168         t2=*this;
169         flag=1;
170     }
171     big=t1.len;
172     for(i=0;i<big;i++)
173     {
174         if(t1.a[i]<t2.a[i])
175         {
176             j=i+1;
177             while(t1.a[j]==0)
178                 j++;
179             t1.a[j--]--;
180             while(j>i)
181                 t1.a[j--]+=MAXN;
182             t1.a[i]+=MAXN+1-t2.a[i];
183         }
184         else t1.a[i]-=t2.a[i];
185     }
186     t1.len=big;
187     while(t1.a[len-1]==0 && t1.len>1)
188     {
189         t1.len--;
190         big--;
191     }
192     if(flag)
193         t1.a[big-1]=0-t1.a[big-1];
194     return t1;
195 }
196 BigNum BigNum::operator*(const BigNum &T)const  //两个大数之间的相乘
197 {
198     BigNum ret;
199     int i,j,up;
200     int temp,temp1;
201     for(i=0;i<len;i++)
202     {
203         up=0;
204         for(j=0;j<T.len;j++)
205         {
206             temp=a[i]*T.a[j]+ret.a[i+j]+up;
207             if(temp>MAXN)
208             {
209                 temp1=temp-temp/(MAXN+1)*(MAXN+1);
210                 up=temp/(MAXN+1);
211                 ret.a[i+j]=temp1;
212             }
213             else
214             {
215                 up=0;
216                 ret.a[i+j]=temp;
217             }
218         }
219         if(up!=0)
220            ret.a[i+j]=up;
221     }
222     ret.len=i+j;
223     while(ret.a[ret.len-1]==0 && ret.len>1)ret.len--;
224     return ret;
225 }
226 BigNum BigNum::operator/(const int &b)const  //大数对一个整数进行相除运算
227 {
228     BigNum ret;
229     int i,down=0;
230     for(i=len-1;i>=0;i--)
231     {
232         ret.a[i]=(a[i]+down*(MAXN+1))/b;
233         down=a[i]+down*(MAXN+1)-ret.a[i]*b;
234     }
235     ret.len=len;
236     while(ret.a[ret.len-1]==0 && ret.len>1)
237         ret.len--;
238     return ret;
239 }
240 int BigNum::operator%(const int &b)const   //大数对一个 int类型的变量进行取模
241 {
242     int i,d=0;
243     for(i=len-1;i>=0;i--)
244         d=((d*(MAXN+1))%b+a[i])%b;
245     return d;
246 }
247 BigNum BigNum::operator^(const int &n)const  //大数的n次方运算
248 {
249     BigNum t,ret(1);
250     int i;
251     if(n<0)exit(-1);
252     if(n==0)return 1;
253     if(n==1)return *this;
254     int m=n;
255     while(m>1)
256     {
257         t=*this;
258         for(i=1;(i<<1)<=m;i<<=1)
259            t=t*t;
260         m-=i;
261         ret=ret*t;
262         if(m==1)ret=ret*(*this);
263     }
264     return ret;
265 }
266 bool BigNum::operator>(const BigNum &T)const    //大数和另一个大数的大小比较
267 {
268     int ln;
269     if(len>T.len)return true;
270     else if(len==T.len)
271     {
272         ln=len-1;
273         while(a[ln]==T.a[ln]&&ln>=0)
274           ln--;
275         if(ln>=0 && a[ln]>T.a[ln])
276            return true;
277         else
278            return false;
279     }
280     else
281        return false;
282 }
283 bool BigNum::operator>(const int &t)const  //大数和一个int类型的变量的大小比较
284 {
285     BigNum b(t);
286     return *this>b;
287 }
288 void BigNum::print()   //输出大数
289 {
290     int i;
291     printf("%d",a[len-1]);
292     for(i=len-2;i>=0;i--)
293       printf("%04d",a[i]);
294     printf("\n");
295 }
296 
297 int main()
298 {
299     //freopen("in.txt","r",stdin);
300     //freopen("out.txt","w",stdout);
301     int m,n;
302     int T;
303     scanf("%d",&T);
304     while(T--)
305     {
306         scanf("%d%d",&m,&n);
307         BigNum tt = 1;
308         for(int i = 1;i < n;i++)
309             tt = tt*m;
310         int tmp = n;
311         for(int i = 2;i <= n;i++)
312         {
313             while( tmp%i == 0 && (tt%i == 0) )
314             {
315                 tmp /= i;
316                 tt = tt/i;
317             }
318         }
319         printf("%d/",tmp);
320         tt.print();
321 
322     }
323     return 0;
324 }

View Code

 

JAVA

 1 import java.io.*;
 2 import java.math.*;
 3 import java.util.*;
 4 
 5 public class Main {
 6     static BigInteger gcd(BigInteger a,BigInteger b)
 7     {
 8         if(b.equals(BigInteger.ZERO))return a;
 9         else return gcd(b,a.mod(b));
10     }
11     public static void main(String arg[])
12     {
13         int T;
14         int n,m;
15         Scanner cin = new Scanner(System.in);
16         T = cin.nextInt();
17         while( T > 0 )
18         {
19             m = cin.nextInt();
20             n = cin.nextInt();
21             BigInteger tmp1 = BigInteger.valueOf(n);
22             BigInteger tmp2 = BigInteger.valueOf(m).pow(n-1);
23             BigInteger tt = gcd(tmp1,tmp2);
24             tmp1 = tmp1.divide(tt);
25             tmp2 = tmp2.divide(tt);
26             System.out.println(tmp1+"/"+tmp2);
27             T--;
28         }
29     }
30 }

View Code

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3346109.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞