Description
一天,小R准备找小h去游泳,当他找到小h时,发现小h正在痛苦地写着一列数,1,2,3,…n,于是就问小h痛苦的原因,小h告诉他,现在他要算1..n这些数里面,1出现的次数是多少,如n=11的时候,有1,10,11共出现4次1,现在给出n,你能快速给出答案么?
Input
一行,就是n,(1<=n<=maxlongint)
Output
一个整数,表示1..n中1出现的次数。
Sample Input
11
Sample Output
4
讨论
看数据范围就知道o(n)是不现实的,对于n中第x位的数字,分三类处理(只找1的个数):
(1)为0时,那么贡献就是n div 10^x*10^(x-1)
循环的次数 * 每次循环的贡献
(2)为1时,(1)+n mod 10^(x-1)+1
在额外的循环中出现的次数
(3) >1时,[(n div 10^x)+1]*10^(x-1)
和(1)相比循环多了1次
var
i:longint;
ans,n:int64;
f:array[0..12] of int64;
s:string;
begin
readln(s);
val(s,n);
f[length(s)]:=1;
for i:=length(s)-1 downto 1 do
f[i]:=f[i+1]*10;
for i:=1 to length(s) do
begin
if i<>1 then
if s[i]='1' then
ans:=ans+n div f[i-1]*f[i]+n mod f[i]+1
else
if s[i]>'1' then
ans:=ans+((n div f[i-1])+1)*f[i]
else
ans:=ans+n div f[i-1]*f[i]
else
if s[i]='1' then
ans:=ans+n mod f[i]+1
else
ans:=ans+f[i];
end;
writeln(ans);
end.