jzoj1535 easygame

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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章