HNUST OJ 1945 个位求和【增强版】

46 篇文章 23 订阅

问题 L: 个位求和【增强版】
时间限制: 1 Sec  内存限制: 128 MB

题目描述
将一个整数区间内所有整数的个位相加并输出。

输入
输入2个int类型整数m和n(m<=n),m与n之间由空格隔开。

输出
将区间[m,n]内所有整数的个位相加并输出。 

样例输入
1 18

样例输出
81

提示
新年福利,温馨提示: 
1)如果用int类型数据,暴力方法只能过90%的数据。最终可能会显示”答案错误10%“或”时间超限10%“。在OI排名表中可以看出得9分。没有优化思路的,得9分后请立刻转做其它题。 
2)如果想过另外10%的数据,请优化方法,且注意如果变量或运算的数据超过int最大值(2147483647),请采用long long定义变量, 变量的scanf和printf 请使用%lld作为格式说明符。

 思路

1. 对于 a \leq b 我们有  Plus(a,b) 为 区间 [a,b] 内所有整数的个位和。

 Plus(a,b)=\left\{\begin{matrix} Plus(a,b) & 0 < a < b \\ Plus(-b,-a)) & a < b < 0 \\ Plus(0,-a) + Plus(0,b)) & a < 0 < b \end{matrix}\right.

2. 找规律 我们拿  a=3,b=\left\{\begin{matrix} 12 \\ 22 \\ 32 \end{matrix}\right.  为例

当 a=3,b=12 时 , 

Plus(a,b) = 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 = \sum_{i=0}^{9}i

当 a = 3 , b = 22 时 , 

Plus(a,b) = 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 = 2*\sum_{i=0}^{9}i

当 a = 3,b=32 时 ,

Plus(a,b) = 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + 1 + 2 = 3*\sum_{i=0}^{9}i

所以规律①  Plus(a,b)=\frac{b-a+1}{10}*\sum_{i=0}^{9}i  当且仅当  (b - a + 1)%10 == 0

然后再以  a=3,b=\left\{\begin{matrix} 13 \\ 14 \\ 15 \end{matrix}\right.  为例

当 a = 3,b = 13 时 ,

Plus(a,b) = 1*\sum_{i=0}^{9} + 3

当 a = 3,b = 14 时 ,

Plus(a,b) = 1*\sum_{i=0}^{9} + 3 + 4

当 a = 3, b = 15 时 ,

Plus(a,b) = 1*\sum_{i=0}^{9} + 3 + 4 + 5

可知 要在规律①上加 (b - a + 1)%10 个数

这个数 从 a + \frac{b-a+1}{10}*10(向下取整,先除再乘,不可抵消)开始

所以答案就出来了。

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll Plus (int a , int b) {
    ll temp=0;
    ll t=b-a+1;
    ll n=t/10;
    ll k=(a+n*10)%10;
    for (int i = 0 ; i < (b-a+1)%10 ; i++) {
        if (k == 10) {
           k = 0 ;
        }
        temp += k;
        k++ ;
    }
    return 45*n + temp ;
}
int main(){
    int m,n;
    ll ans=0;
    cin >> m >> n ;
    if (n < 0) {
        ans = Plus(-n,-m) ;
    } else if (m < 0) {
        ans = Plus(0,-m) + Plus(0,n) ;
    } else {
        ans = Plus(m,n) ;
    }
    cout << ans ;
    return 0;
}
/**************************************************************
    Problem: 1945
    User: 21XXXXXXXX
    Language: C++
    Result: 正确
    Time:0 ms
    Memory:2024 kb
****************************************************************/
// 这里提供一个更容易的方法,建议学习这个

#include <bits/stdc++.h>
using namespace std;
 
// 2023 OneWan
 
long long get(int n) { // 此函数求 0 到 n 的个位和
    if (n < 0) return 0LL;
    return 45LL * (n / 10) + (n % 10) * (n % 10 + 1) / 2;
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int m, n;
    cin >> m >> n;
    if (m > 0) cout << get(n) - get(m - 1);
    else if (n < 0) cout << get(-m) - get(-n - 1);
    else cout << get(n) + get(-m);
    return 0;
}
/**************************************************************
    Problem: 1945
    User: 21XXXXXXXX
    Language: C++
    Result: 正确
    Time:0 ms
    Memory:2180 kb
****************************************************************/

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值