程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4762 Cut the Cake(概率+推理+高精度)

HDU 4762 Cut the Cake(概率+推理+高精度)

編輯:C++入門知識

Cut the Cake

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


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

題意:M個小伙伴分蛋糕,有N個草莓隨機分布在蛋糕上,你去把蛋糕平均切,並優先選擇一塊,問你能拿到所有草莓的概率。

思路:以最外面的一個草莓為第一刀為切的位置,這樣一共有N種開刀位置,然後剩下N-1個草莓,每個的概率為1/M.如此以來概率為N / M ^ (N - 1); 要使用高精度,並且化簡輸出。

代碼:

#include 
#include 
#include 

using namespace std;
const int N = 1005;

struct bign {
    int len, sex;
    int s[N];

    bign() {
	this -> len = 1;
	this -> sex = 0;
	memset(s, 0, sizeof(s));
    }


    bign operator = (const char *number) {
	int begin = 0;
	len = 0;
	sex = 1;
	if (number[begin] == '-') {
	    sex = -1;
	    begin++;
	}
	else if (number[begin] == '+')
	    begin++;

	for (int j = begin; number[j]; j++)
	    s[len++] = number[j] - '0';
	return *this;
    }
    bign operator = (int number) {
	char string[N];
	sprintf(string, "%d", number);
	*this = string;
	return *this;
    }
    bign (int number) {*this = number;}
    bign (const char* number) {*this = number;}

    bign change(bign cur) {
	bign now;
	now = cur;
	for (int i = 0; i < cur.len; i++)
	    now.s[i] = cur.s[cur.len - i - 1];
	return now;
    }

    void delZore() {	// 刪除前導0.
	bign now = change(*this);
	while (now.s[now.len - 1] == 0 && now.len > 1) {
	    now.len--;
	}
	*this = change(now);
    }

    void put() {    // 輸出數值。
	delZore();
	if (sex < 0 && (len != 1 || s[0] != 0))
	    cout << "-";
	for (int i = 0; i < len; i++)
	    cout << s[i];
    }

    bign operator * (const bign &cur){  
	bign sum, a, b;
	sum.len = 0; 
	a = a.change(*this);
	b = b.change(cur);

	for (int i = 0; i < a.len; i++){  
	    int g = 0;  

	    for (int j = 0; j < b.len; j++){  
		int x = a.s[i] * b.s[j] + g + sum.s[i + j];  
		sum.s[i + j] = x % 10;  
		g = x / 10;  
	    }  
	    sum.len = i + b.len;  

	    while (g){  
		sum.s[sum.len++] = g % 10;  
		g = g / 10;  
	    }  
	}  
	return sum.change(sum);  
    }  

    bign operator / (int k) {  // 高精度求商低精度。
	bign sum;  
	sum.len = 0;  
	int num = 0;  
	for (int i = 0; i < len; i++) {  
	    num = num * 10 + s[i];  
	    sum.s[sum.len++] = num / k;  
	    num = num % k;  
	}  
	return sum;  
    }

    int operator % (int k){  
	int sum = 0;  
	for (int i = 0; i < len; i++){  
	    sum = sum * 10 + s[i];  
	    sum = sum % k;  
	}  
	return sum;  
    } 

    bool operator < (const bign& b) const {
	if (len != b.len)
	    return len < b.len;
	for (int i = 0; i < len; i++)
	    if (s[i] != b.s[i])
		return s[i] < b.s[i];
	return false;
    }
    bool operator > (const bign& b) const { return b < *this; }
    bool operator <= (const bign& b) const { return !(b < *this); }
    bool operator >= (const bign& b) const { return !(*this < b); }
    bool operator != (const bign& b) const { return b < *this || *this < b;}
    bool operator == (const bign& b) const { return !(b != *this); }
};

int t, n, M;
bign zero = 0;

int main () {
    scanf("%d", &t);
    while (t--) {
	scanf("%d%d", &M, &n);
	bign m = M;
	bign ans = 1;
	for (int i = 1; i < n; i++)
	    ans = ans * m;
	for (int i = n; i >= 2; i--) {
	    if (n % i == 0 && ans % i == 0) {
		n /= i;
		ans = ans / i;
	    }
	    if (n == 1) break;
	}
	printf("%d/", n);
	ans.put();
	printf("\n");
    }
    return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved