真·MdOI R3 A.Number题解

· · 题解

这是一篇C和C++通用的题解。

再次声明:本题不是高精模板题,虽然也可以练习高精。请各位同学选择对自己最有益的一种或几种方法AC本题。

由于yummy算错日期,官方题解足足晚交了一天,题解区已经被常见的数 0 法和Python法等占满了。

既然如此,如果想看常规解法的同学可以直接跳过本题解,本题解重点放在神奇的sprintf法。

首先,对于 k\le 18 的情况我们仍然需要特判。计算 10^k 可以使用for循环,math.h中的pow函数或者手动打表。

我们尝试进行一些小学生计算:

观察这个竖式,可以将 10^k>x 的情况表示成:

先输出字符1,然后将 x 以固定的长度 k 输出,不足 k 位用前导零补齐。

在C/C++中,printf就可以上面的操作:

//在主函数中加入这句
printf("%019d",19810);

你的输出是不是0000000000000019810

因此,如果我们要计算 10^{20}+x,我们可以这么写:

char ord[114]="1%020lld";
printf(ord,x);//相当于printf("1%020lld",x);

我们为了将 k 填入形如"1%0klld"语句中,我们先将这个字符串存为char ord[],然后我们printf(ord,x);即可。

接下来我们需要将 k"1%0klld"的形式输出到ord里面,我们可以使用sprintf函数。

sprintf函数用法几乎和printf用法相同,唯一的不同点是sprintf需要在最前面加一个char[]表示输出的目标位置。因此,对于这道题我们可以这么写:

//假设k=6,x=35
char ord[15];
sprintf(ord,"1%%0%dlld",k);//想输出%要在语句中填入%%
//ord现在是"1%06lld"
printf(ord,x);//1000035

那么我们就可以很快地写出完整代码(别看16行,只有250B,本来还能再短一点):

#include<stdio.h>
#include<math.h>
int k;long long x;
char ord[15];
int main()
{
    scanf("%d%lld",&k,&x);
    if(k<=18)
        printf("%lld",x+(long long)pow(10ll,k));
        //这里实际上不推荐这么用,pow函数有很大的精度误差,虽然我本地和你谷评测姬都能AC,但据说有些环境样例会输出1000000006.
    else
    {
        sprintf(ord,"1%%0%dlld",k);
        printf(ord,x);
    }
    return 0;
}