数列

来源:互联网 发布:苹果淘宝直播怎么加入 编辑:程序博客网 时间:2024/04/28 07:19

前言
“从正面看,是伟大的神(God);从反面看,是卑鄙小人(dog)。其实,人们所犯的罪恶(evil),反过来,正是为了活着(live)。”欢迎来到嘟嘟课堂。今天我们讲一道看似特别特别水一看数据范围限制吓你一跳的题——数列!
题目描述
Smart非常喜欢研究数列规律,一天他在纸上写着一列数:1,2,3,…,N,突然他想到:1,2,3,…,N这些数里面,1出现的次数是多少?如N=11的时候,有1, 10, 11共出现4次1。
现在告诉你N,你能帮助Smart快速给出答案么?
输入
第一行包括一个整数N。
输出
输出一行一个整数,表示这个数列1~N中1出现的次数。
样例输入
11
样例输出
4
数据范围限制
30%的数据:1≤N≤200;
100%的数据:1≤N≤2*10^8。
思路
这道题相信大家一看到题目描述就觉得水的不得了,但是一看数据范围限制就会吓一大跳,连O(n)的方法都过不了。这就是一道经典的数论题。那么这时候我们就要找规律,简化一下程序:
个位的1:N div 10+如果n mod 10 >0就是1,否则是0
十位的1:N div 100*10+min(N mod 100,19)-9
百位的1:N div 1000*100+min(N mod 1000,199)-99
……
以此类推,我们可以得到一条公式。
if (i mod 10=1) then inc(ans,i div 10*k+n mod k+1)
else if (i mod 10=0) then inc(ans,i div 10*k)
else inc(ans,(i div 10+1)*k);
不懂的童鞋可以自己多理解几次,其实就是一道小学奥数题。还是不懂的可以去了解一下小学的数论。
代码

var        i,k,n,ans:int64;begin        readln(n);        k:=1;        while n>=k do        begin                i:=n div k;                if (i mod 10=1) then inc(ans,i div 10*k+n mod k+1)                        else if (i mod 10=0) then inc(ans,i div 10*k)                                else inc(ans,(i div 10+1)*k);                k:=k*10;        end;        writeln(ans);end.
原创粉丝点击