1 条题解

  • 0
    @ 2025-8-24 22:23:33

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar yummy
    这个人是时代的眼泪,什么也没有留下

    搬运于2025-08-24 22:23:33,当前版本为作者最后更新于2020-08-12 07:53:16,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


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

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

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

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


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


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

    temp.jpg

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

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

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

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

    你的输出是不是0000000000000019810

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

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

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

    接下来我们需要将 kk"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;
    }
    
    • 1

    信息

    ID
    5742
    时间
    1000ms
    内存
    128MiB
    难度
    1
    标签
    递交数
    0
    已通过
    0
    上传者