Question: Give Mn and ask for C (m, n ).
Train of Thought: If you get all the formulas, It's only 100. The key to brute force is high accuracy. If you follow the algorithm "it allows you to do what you do", it is clear that you need to write a high-precision division. However, it can be proved that this division will not produce the remainder. Therefore, we can analyze number theory and avoid high-precision division.
The method is to forcibly calculate the prime factor of each number, and then eliminate the prime factor of the same divisor and divisor, And the last divisor will be deleted. In this way, we only need to perform high-precision multiplication.
Code:
#include <cstdio>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>#define MAX 110#define BASE 1000using namespace std;int n,m;int factor[MAX];struct BigInt{int num[MAX],len;BigInt(int _ = 0) {memset(num,0,sizeof(num));if(_) {len = 1;num[1] = _;}elselen = 0;}BigInt operator *(int a) {BigInt re;int temp = 0;for(int i = 1; i <= len; ++i) {re.num[i] = num[i] * a + temp;temp = re.num[i] / BASE;re.num[i] %= BASE;}re.len = len;while(temp) {re.num[++re.len] = temp % BASE;temp /= BASE;}return re;}void operator *=(int a) {*this = *this * a;}};ostream &operator <<(ostream &os,const BigInt &a) {os << a.num[a.len];for(int i = a.len - 1; i; --i)os << fixed << setfill('0') << setw(3) << a.num[i];return os;}inline void Divide(int x,int c){for(int i = 2; i * i <= x; ++i)if(x % i == 0)while(x % i == 0) {factor[i] += c;x /= i;}if(x != 1)factor[x] += c;}int main(){while(scanf("%d%d",&n,&m),m + n) {memset(factor,0,sizeof(factor));for(int i = 1; i <= n; ++i)Divide(i,1);for(int i = 1; i <= m; ++i)Divide(i,-1);for(int i = 1; i <= n - m; ++i)Divide(i,-1);BigInt ans(1);for(int i = 1;i <= 100; ++i)for(int j = 1; j <= factor[i]; ++j)ans *= i;cout << n << " things taken " << m << " at a time is " << ans <<" exactly." << endl;}return 0;}
Poj 1306 combinations high-precision Multiplication