hqd125


私信TA

用户名:hqd

访问量:2659

签 名:

若MS WPS没有把握,何不把时间花在C上面?一举两得

等  级
排  名 347
经  验 5127
参赛次数 5
文章发表 6
年  龄 0
在职情况 教师
学  校
专  业

  自我简介:

学练同步,知行合一,希望大家都能理论与动手结合,拒绝理论派! 前期扎实学习打基础,后期快乐练习过二级!

首先 这个题的答案为:18446744073709551615

                              

这个题的【置顶加精】【优质题解】答案18446744073709551616是错误的


因为1+2+4+…………,他肯定是一个奇数,怎么可能是一个偶数呢


其次,这个题的样例输出18446744073709552000也是错误的



那么,我们如何得出正确的结果呢?


首先,这个题的解题思路很简单,就是常规的循环加和,但是因为最后一个数字是2^63次方很大,常用的int存放不下,那么我们就需要用其他方法。


对于任意大的数,数组是最好的解决办法,这是  【花露水和暖壶】关于数组表示大数的解决方案,可以看看  数组表示大数

 

对于不是非常大的数,其实我们也是可以使用double ,double的有效数字为15-16位,用来存15位及以内的整数是没问题的,超过了的话,它只对前15位数字的有效性进行保证,后面的就不保证了。


那么对于这个题并不适用,需要注意。


这里我放一下 数据类型取值范围及位数图标


图表:C/C++基础数字类型的取值范围


类型                                                                    取值范围                                                 位数

unsigned   int                                                      0~4294967295                                    10位

int                                                      2147483648~2147483647                                    10位

unsigned long                                                     0~4294967295                                    10位

long                                                   2147483648~2147483647                                    10位

long long                        -9223372036854775808~9223372036854775807                   19位

unsigned long long                                             0~18446744073709551615                 20位

__int64                            -9223372036854775808~9223372036854775807                   19位

unsigned __int64                                                 0~18446744073709551615                  20位



参考代码:

#include<stdio.h>
int main()
{
    int a[100]= {0};       //存放加和的数组,每位对应一个数字  0-99分别为低位到高位
    int b[100]= {1,0};     //存放每次的数字 ,每位对应一个数字  0-99分别为低位到高位
                           //这里我直接将第一个格子的1先放进来了
    int temp1,temp2;
    int i,j,flag1,flag2;    //flag1,flag2为存放进位,2个数字相加,进位最大只有1

    for( i =1; i<=64; i++)   //从第一个格子到64个格子,进行累加
    {
        flag1=flag2=0;                   //每次累加前将进位置0
        for( j=0; j<100; j++)            //将b[100]里面的数字加到a[100]里面去
        {
            temp1 = a[j]+b[j]+flag1;     //将每一位进行加和,并将上一位有进位的加进去
            a[j]=temp1%10;                 //若大于等于10,则取个位
            if(flag1) flag1=0;            //将进位置0
            flag1=temp1/10;               //取这一位的进位,0或者1
        }
        for( j=0; j<100; j++)            //计算下一个格子 方法跟上面累加相同
        {
            temp2 = 2*b[j]+flag2;
            b[j]=temp2%10;
            if(flag2) flag2=0;
            flag2=temp2/10;
        }
    }

    //结果输出
    for( i=99; i>=0; i--)       // 因为初始化时是从低到高位存入的,那么取出时因倒叙取出
        if(a[i]!=0)            //100位太长,需要将高位没意义的0全去掉
        {
            for(j=i; j>=0; j--)
                printf("%d",a[j]);
            break;
        }

    return 0;
}

观察代码,还可以优化一下

#include<stdio.h>
int main()
{
    int a[100]= {0};      
    int b[100]= {1,0};     
                          
    int temp1,temp2;
    int i,j,flag1,flag2;   
    
    for( i =1; i<=64; i++)  
    {
        flag1=flag2=0;                   
        for( j=0; j<100; j++)           
        {
            temp1 = a[j]+b[j]+flag1;    
            a[j]=temp1%10;                 
            if(flag1) flag1=0;            
            flag1=temp1/10;             //并不是所有的相同for循环都能合并
                                        //这里因为是先计算加和,已经使用了b[j],而且后面不再使用
                                        //所以可以对b[j]进行操作
       
            temp2 = 2*b[j]+flag2;
            b[j]=temp2%10;
            if(flag2) flag2=0;
            flag2=temp2/10;
        }
    }
    //输出计算结果 
    for( i=99; i>=0; i--)      
        if(a[i]!=0)           
        {
            for(j=i; j>=0; j--)
                printf("%d",a[j]);
            break;
        }

    return 0;
}


 

0.0分

7 人评分

  评论区

yyds
2022-10-10 21:07:05
膜拜大佬
2022-10-10 21:06:40
  • «
  • 1
  • »