现在的位置: 首页 > 综合 > 正文

1的数目

2013年06月26日 ⁄ 综合 ⁄ 共 1137字 ⁄ 字号 评论关闭

 

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;
	}
	
}

抱歉!评论已关闭.