一.题目链接
二.思路
思路参考:https://www.acwing.com/solution/content/48085/
三.代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 150, mod = 1000;
int k, x;
int f[1000][100][N];//f[i][j][k]:C[i][j]的第k位
int qmi(int a, int b)
{
int res = 1;
while(b)
{
if(b & 1) res = (ll)res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void add(int c[N], int a[N], int b[N])
{ //枚举每一位从低位开始
int t = 0;//进位
for(int i = 0; i < N; i ++)
{
t = a[i] + b[i] + t;
c[i] = t % 10;
t /= 10;
}
}
int main()
{
cin >> k >> x;
//求n
int n = qmi(x % mod, x);//求n
//求组合数C(n - 1, k - 1) n个物品中间有n - 1个空隙,插k - 1个板子可以形成k个数
//递推式:C(i,j) = C(i - 1,j - 1) + C(i - 1, j)
for(int i = 0; i < n; ++ i)
for(int j = 0; j <= i && j < k; ++ j)//注意到这里的j < k优化。很容易错
if(!j) f[i][j][0] = 1;
else add(f[i][j], f[i - 1][j], f[i - 1][j - 1]);
//输出答案 C(n - 1, k - 1)
int it = N - 1;
while(!f[n - 1][k - 1][it]) --it;//去除前导0
while(it >= 0) cout << f[n - 1][k - 1][it--];//输出结果 逆序输出
return 0;
}
四.总结
- 高精度数组的用法:
int f[N][N][M];//多开一维用来存储位置
//高精度加法函数 c = a + b
void add(int c[M], int a[M], int b[M])
{
int t = 0;//进位
//枚举每一位
for(int i = 0; i < M; i ++)
{
t = t + a[i] + b[i];
c[i] = t % 10;//当前这一位的答案
t = t % 10;//得到进位
}
}
//输出
int t = n - 1;//得到最高位
while(!f[i][j][t]) t--;//去除前导0
while(t >= 0) cout << f[i][j][t--];
return 0;