AGC 011 E Increasing Numbers - 贪心

本文介绍了一种求解特定数学问题的算法——如何找到至少多少个非递减的数字,其数字和为N。通过将问题转化为求解一系列特定形式的数字之和,提出了一种基于暴力进位的解决方案,证明了该算法的时间复杂度为O(len(n)),并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:问至少多少各位数不减的数字,其和为N。len(N)<=5e5。
题解:各位数字不减的数字可以表示为9个每位都是1的数字之和(位数可以等于0)。一个a位都是1都数字是10a−19\frac{10^a-1}9910a1。假设用了k个数字,那么相当于是找一些a[i]使得∑i=19k10ai=9n+9k\sum_{i=1}^{9k}10^{a_i}=9n+9ki=19k10ai=9n+9k成立。这个可以证明等价于9n+9k9n+9k9n+9k的各位数字之和不超过9k9k9k。可以显然发现答案最坏也就是O(len(n))O(len(n))O(len(n))级别的,而暴力进位的复杂度可以被证明是均摊O(len(n))O(len(n))O(len(n))的。这样就做完了。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;const int N=500010;char str[N];
struct bignum{
	int a[N*10],n,s;bignum() { memset(a,0,sizeof a),n=s=0; }
	inline int input() { scanf("%s",str+1),n=(int)strlen(str+1);rep(i,1,n) a[n-i+1]=str[i]-'0';return 0; }
	inline bignum& operator+=(int t)
	{	s-=a[1],a[1]+=t;int i=1,jw=a[1]/10;for(;jw;s-=a[i+1],a[i+1]+=jw,a[i]%=10,jw=a[++i]/10);rep(j,1,i) s+=a[j];n=max(n,i);return *this;	}
	inline bignum& operator*=(int t)
	{	rep(i,1,n) a[i]*=t;for(int i=1,jw=a[1]/10;i<=n||jw;a[i+1]+=jw,a[i]%=10,jw=a[++i]/10);while(a[n+1]) n++;s=0;for(int i=1;i<=n;i++) s+=a[i];return *this;	}
}x;
int main() { x.input(),(x*=9)+=9;for(int k=1;;x+=9,k++) if(x.s<=9*k) return !printf("%d\n",k);return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值