AGC 011 E Increasing Numbers - 贪心

题目大意:问至少多少各位数不减的数字,其和为N。len(N)<=5e5。
题解:各位数字不减的数字可以表示为9个每位都是1的数字之和(位数可以等于0)。一个a位都是1都数字是 1 0 a − 1 9 \frac{10^a-1}9 910a1。假设用了k个数字,那么相当于是找一些a[i]使得 ∑ i = 1 9 k 1 0 a i = 9 n + 9 k \sum_{i=1}^{9k}10^{a_i}=9n+9k i=19k10ai=9n+9k成立。这个可以证明等价于 9 n + 9 k 9n+9k 9n+9k的各位数字之和不超过 9 k 9k 9k。可以显然发现答案最坏也就是 O ( l e n ( n ) ) O(len(n)) O(len(n))级别的,而暴力进位的复杂度可以被证明是均摊 O ( l e n ( 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; }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值