AcWing 1308. 方程的解(高精度+递推+隔板法)

一.题目链接

二.思路

在这里插入图片描述
思路参考: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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值