题目大意:问至少多少各位数不减的数字,其和为N。len(N)<=5e5。
题解:各位数字不减的数字可以表示为9个每位都是1的数字之和(位数可以等于0)。一个a位都是1都数字是
1
0
a
−
1
9
\frac{10^a-1}9
910a−1。假设用了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; }