题意
定义一个数是好的当且仅当其十进制表示下从高位到低位每一位都是单调不降的。给出n,问n最少可以表示成多少个好数之和。
n<=10^500000
分析
这题首先要发现一个性质:每个好数都可以表示成9个全1数(包括0)的和的形式。
一个全1数又可以表示成10x−1910x−19的形式。
也就是说,我们要找到最小的k使得∑9ki=110a[i]−19=n∑i=19k10a[i]−19=n
把式子画一下就变成了∑9ki=110a[i]=9n+9k∑i=19k10a[i]=9n+9k
不难发现这条式子的意义就是9n+9k9n+9k的数位之和等于9k9k。
那么我们就可以枚举k然后判定即可。
不难发现k并不会太大。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=500005;
const int maxn=N*5;
int tot,a[maxn+5];
char str[N];
void mul(int x)
{
int s,g=0;
for (int i=maxn;i>=1;i--)
{
s=a[i]*x+g;
a[i]=s%10;
g=s/10;
}
}
void add(int x)
{
a[maxn]+=x;tot+=x;
for (int i=maxn;i>=1&&a[i]>=10;i--)
{
tot-=a[i-1]+a[i];
a[i-1]++;a[i]-=10;
tot+=a[i-1]+a[i];
}
}
int main()
{
scanf("%s",str);
int len=strlen(str);
for (int i=0;i<len;i++) a[maxn-i]=str[len-i-1]-'0';
mul(9);
for (int i=1;i<=maxn;i++) tot+=a[i];
for (int k=1;;k++)
{
add(9);
if (k*9>=tot) {printf("%d",k);break;}
}
return 0;
}