真·MdOI R3 A.Number题解

yummy

2020-08-12 07:53:16

Solution

**这是一篇C和C++通用的题解。** **再次声明:本题不是高精模板题,虽然也可以练习高精。请各位同学选择对自己最有益的一种或几种方法AC本题。** 由于yummy算错日期,官方题解足足晚交了一天,题解区已经被常见的数 $0$ 法和Python法等占满了。 既然如此,如果想看常规解法的同学可以直接跳过本题解,本题解重点放在神奇的`sprintf`法。 --- 首先,对于 $k\le 18$ 的情况我们仍然需要特判。计算 $10^k$ 可以使用for循环,`math.h`中的`pow`函数或者手动打表。 --- 我们尝试进行一些小学生计算: ![temp.jpg](https://i.loli.net/2020/07/28/DKreMb15lR2FYGO.jpg) 观察这个竖式,可以将 $10^k>x$ 的情况表示成: > 先输出字符1,然后将 $x$ 以固定的长度 $k$ 输出,不足 $k$ 位用前导零补齐。 在C/C++中,`printf`就可以上面的操作: ```c //在主函数中加入这句 printf("%019d",19810); ``` 你的输出是不是`0000000000000019810`? 因此,如果我们要计算 $10^{20}+x$,我们可以这么写: ```c 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[]`表示输出的目标位置。因此,对于这道题我们可以这么写: ```c //假设k=6,x=35 char ord[15]; sprintf(ord,"1%%0%dlld",k);//想输出%要在语句中填入%% //ord现在是"1%06lld" printf(ord,x);//1000035 ``` 那么我们就可以很快地写出完整代码(别看16行,只有250B,本来还能再短一点): ```c #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; } ```