AtCoder Grand Contest 011 E - Increasing Numbers 乱搞+高精度

题意

定义一个数是好的当且仅当其十进制表示下从高位到低位每一位都是单调不降的。给出n,问n最少可以表示成多少个好数之和。
n<=10^500000

分析

这题首先要发现一个性质:每个好数都可以表示成9个全1数(包括0)的和的形式。
一个全1数又可以表示成 10x19 10 x − 1 9 的形式。
也就是说,我们要找到最小的k使得 9ki=110a[i]19=n ∑ i = 1 9 k 10 a [ i ] − 1 9 = n
把式子画一下就变成了 9ki=110a[i]=9n+9k ∑ i = 1 9 k 10 a [ i ] = 9 n + 9 k
不难发现这条式子的意义就是 9n+9k 9 n + 9 k 的数位之和等于 9k 9 k
那么我们就可以枚举k然后判定即可。
不难发现k并不会太大。

代码

#include
#include
#include
#include
#include
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;i1]-'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;
}

你可能感兴趣的:(乱搞)