2490. 数页码
★☆ 输入文件:count_zqm.in
输出文件:
count_zqm.out
简单对比
时间限制:1 s 内存限制:256 MB
【题目描述】
一本书的页码是从 1-n 编号的连续整数: 1, 2, 3, ... , n。请你求出全部页码中
所有单个数字的和,例如第 123 页,它的和就是 1+2+3=6。
【输入格式】
一行为 n(1 <= n <= 10^9)。
【输出格式】
一行,代表所有单个数字的和。
【样例输入】
3456789
【样例输出】
96342015
这道题一看就是数学问题, 但是也可以暴力+打表, 前10^6暴力, 后面的打表, 有人就是这样过的, 好思路, get;
我用的是数学方法, 自己瞎模拟一下就会得出规律的, 但是因为long long 和 int 的问题, 调了一大会儿, 后来才知道, int爆啦, 爆啦;
得出结论:long long 大法好;
代码来啦:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define LL long long
LL a[12], ans, n;
LL pow(int x, int n) {
int cnt=1;
for(int i=1; i<=n; i++) cnt*=x;
return cnt;
}
void zzx(LL x, int d, int num) {
LL s=pow(10, d);
LL y=x%10;
/*for(int i=0; i<y; i++) {
ans+=a[d]+s*i;
}*/ //还是枚举大法好;简单明了, 不爆int;
if(y>0) ans+=y*a[d]+(y*(y-1))/2*s; //就是这里, 调了一大会儿; 这句话的效果和注释掉的代码一样;
ans+=(num+1)*y;
num+=s*y;
x/=10;
if(!x) {
return;
}
zzx(x, d+1, num);
}
void init() {
cin>>n;
for(int i=1; i<=10; i++) a[i]=a[i-1]*10+pow(10, i-1)*5*9;
zzx(n, 0, 0);
cout<<ans<<endl;
}
int main() {
freopen("count_zqm.in", "r", stdin);
freopen("count_zqm.out", "w", stdout);
init();
return 0;
}