import java.util.Scanner; /* * @topic:编程之美第一章,1的数目 */ public class OneNum{ public static void main(String[] args) { //System.out.println("Hello Landor!"); Scanner sc = new Scanner(System.in); long n = sc.nextLong(); System.out.println(f(n)); //System.out.println(Long.MAX_VALUE); } /* * 常规思维比较简单,但是效率太低 public static long f(long n){ long sum = 0 ; for(long i = 1 ; i <= n ; i++){ sum += oneCount(i); } return sum; }//遍历1-n 将1的个数累加 public static long oneCount(long n){ long one = 0 ; while(n!=0){ one += (n%10==1?1:0); n /= 10; } return one; }//求出每个数中1的个数 */ /* * 第二种方法是通过只分析N而得到的,只考虑在N的每个位数上1出现的次数即可 * 比如 12X4: 那么在十位上出现1的个数即为 : 注:此时12为高位、X为当前位、4为低位 * 当X=0时,有 10-19、110-119、210-219、、、1110-1119 一共12*10=120个,仅由高位决定 * 当X=1时,有 上面的120个加上1210、1211、1212、1213、1214 有 120+(4+1) = 125个,由高位低位共同决定 * 当X=2-9时,有 10-19、110-119、210-219、、、1110-1119、1210-1219 一共(12+1)*10=130个,仅由高位决定 */ public static long f(long n){ long iCount = 0;//总数 long iFactor = 1; long low = 0;//低位 long iCurrent = 0;//当前位 long high = 0 ;//高位 while(n/iFactor != 0){ low = n - (n/iFactor)*iFactor; iCurrent = (n/iFactor)%10; high = n/(iFactor*10); switch((int)iCurrent){ case 0://X=0 iCount += high * iFactor; break; case 1://X=1 iCount += high * iFactor + low +1 ; break; default://X=2-9 iCount += (high+1) * iFactor; break; } iFactor *= 10; } return iCount; } }