Problem 2113 Jason的特殊爱好(计算1的个数)

Problem Description

Jason很喜欢数字,特别是1这个数字,因为他觉得1有特殊的含义。为了让更多的人喜欢上1,他决定出一题关于1的水题(每个人都喜欢水题)。

 Input

输入数据中有多组数据,每组数据输入为两个正数,a,b(1<=a,b<=10^18)。

 Output

输出a到b之间的整数包含多少个1。

 Sample Input

1 1000

 Sample Output


301



/**
 * 思路:先记算1-a中所包含的1,在记算1-b中所包含的1,两者之差就是所要求的、 
 * */
import java.math.BigInteger;
import java.util.Scanner;

public class Fzu2113 {

	public static void main(String[] args) {

		Scanner s  = new Scanner(System.in);
		while(s.hasNext())
		{
			String startstr = s.next();
			String endstr = s.next();
			BigInteger start = new BigInteger(startstr);
			BigInteger end = new BigInteger(endstr);
			
			if(start.compareTo(end)==1 || start.compareTo(end)==0)
			{
				System.out.println(0);
			}else
			{
				BigInteger smallnums = count1sums(start.subtract(new BigInteger("1")));
				BigInteger bignums = count1sums(end);
				System.out.println(bignums.subtract(smallnums).toString());
			}
		}
		
	}

	/**
	 * 计算sum中出现1的次数,方法就是  分别计算每一位上出现1的次数,然后加起来,
	 * 而每一位上1的个数,受高位,当前位和低位的影响
	 * 
	 * 如果当前位为0,1的个数只受高位影响,个数为高位的数*当然所在位(个1,十10,百100,千1000)
	 * 如果当前位为1,则1的个数受高位和低位影响,个数为高位的数*当然所在位(个1,十10,百100,千1000)
	 *               加上低位数字+1;
	 * 如果当前位大于1,1的个数只受高位影响,个数为更高位数字加1然后在乘以当前位(个1,十10,百100,千1000)
	 * 
	 * @param iCount 记录多少个1
	 * @param iFactor 记当当前所在的位
	 * @param iLowerNum 记录低位的数字
	 * @param iHigherNum 记录高位的数字
	 * @param iCurrNum 记录当前位的数字
	 * 
	 * */
	public static BigInteger count1sums(BigInteger sum)
	{
		BigInteger iCount = new BigInteger("0");
		BigInteger iFactor = new BigInteger("1");
		BigInteger iLowerNum = new BigInteger("0");
		BigInteger iCurrNum = new BigInteger("0");
		BigInteger iHigherNum = new BigInteger("0");
		BigInteger zero = new BigInteger("0");
		BigInteger one = new BigInteger("1");
		BigInteger ten = new BigInteger("10");
		while(sum.divide(iFactor).compareTo(zero)!=0)
		{
			iLowerNum = sum.subtract(sum.divide(iFactor).multiply(iFactor));
			iCurrNum = sum.divide(iFactor).mod(ten);
			iHigherNum = sum.divide(iFactor.multiply(ten));
			
			if(iCurrNum.compareTo(zero)==0)
			{
				iCount = iCount.add(iHigherNum.multiply(iFactor));
			}else if(iCurrNum.compareTo(one)==0)
			{
				iCount = iCount.add(iHigherNum.multiply(iFactor).add(iLowerNum).add(one));
			}else
			{
				iCount = iCount.add(iHigherNum.add(one).multiply(iFactor));
			}
			
			iFactor = iFactor.multiply(ten);
			
		}
		
		return iCount;
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值