id="c_n9"width="1920"height="990"style="position: fixed; top: 0px; left: 0px; z-index: -1; opacity: 0.5;">

个位求和题解

个位求和【增强版】
题目描述
将一个整数区间内所有整数的个位相加并输出。
输入
输入2个int类型整数m和n(m<=n),m与n之间由空格隔开。
输出
将区间[m,n]内所有整数的个位相加并输出。
样例输入
1 18
样例输出
81

ps:这一题我大一的时候写过,同时也AC过,但是代码风格确实太烂的而且有点臃肿,索性将其再写了一遍

算法思路

其实这题的话,就是一个简单的数学题,只要你能够推出这个个位求和的公式,那么你就能够做出

这里我简单的分析一下,对于给定区间的数m–n,其个位数可以分为m%10-9,0-9…0-9,0-n%10,对于中间的很多个0-9可以求出他们的和为45,对于左右两边的数字范围其实也可以采取的方式是补齐0-9的区间,这样就可以通过45这个特定值来计算

*左边补齐的数和:left_sum=((left-1)left)/2.0;

右边补齐的数和:right_sum=((right+10)*(9-right))/2.0;

在补齐后通过相关关系可以算出有多少个0-9:cnt=(len+left_len+right_len)/10;

那么总的sum为:sum=cnt*45-left_sum-right_sum;

ok,在知道了这些就可以知道你需要求的sum和是多少了,然后根据n,m的正负来分段计算,同时注意本题只是计算个位数,所以均为正数

源码

ps:建议不要照搬

#include<iostream>
#include<cstdio>
using namespace std;
long long Sum(long long left,long long right,long long len)
{
    long long left_sum=0,right_sum=0;
    long long left_len,right_len;
    left_len=right_len=0;
    if(left!=0)//计算左补齐
    {
        left_sum=((left-1)*left)/2.0;
        left_len=left;
    }
    if(right!=9)//计算右补齐
    {
        right_sum=((right+10)*(9-right))/2.0;
        right_len=9-right;
    }
    long long cnt=0;//表示有多少个45,
    cnt=(len+left_len+right_len)/10;//算总个数
    long long sum=0;
    sum=cnt*45-left_sum-right_sum;
    return sum;
}
int main()
{
    long long m,n;
    scanf("%lld %lld",&m,&n);
    //通过补位来求
    long long left=m%10,right=n%10;
    long long sum=0;
    if(m>=0) sum=Sum(left,right,n-m+1);
    else if(n<=0) sum=Sum(-right,-left,n-m+1);
    else sum=Sum(0,right,n+1)+Sum(0,-left,-m+1);
    printf("%lld",sum);
    return 0;
}

时间复杂度分析:O(1)

嗯,就是这样,有啥建议or问题请私聊我

posted @ 2022-01-29 10:53  hellozmc  阅读(136)  评论(0编辑  收藏  举报