题目地址:http://ac.jobdu.com/problem.php?pid=1373
题目描述:
亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他。问题是:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
输入:
输入有多组数据,每组测试数据为一行。
每一行有两个整数a,b(0<=a,b<=1,000,000,000)。
输出:
对应每个测试案例,输出a和b之间1出现的次数。
样例输入:
0 5
1 13
21 55
31 99
样例输出:
1
6
4
7
【解题思路】
这个题其实和题目1491:求1和2的个数完全一样。
不一样的地方只是输入。一个输入的是数字,一个是字符串,处理方式完全一样。
来分析一下思路。尽量简单一点。
1)、假设有一个五位数,32145
那么从1到32145一共包含多少个1呢。
我们对百位数1开始分析。也就是百位数为1的个数一共有多少个呢。
对于它的高位来说,是32。一共有00100~00199,01100~01199,02100~02199,.....,31100~31199,一共是32*100个数。
对于它的地位来说,是45。一共有100~145,46个数。
加起来是highNum*100+lowNum+1;
2)、那如果百位不是1呢,是0怎么算呢。
如果是32045,
对于它的高位来说,是32。一共有00100~00199,01100~01199,02100~02199,.....,31100~31199,一共是32*100个数。
对于它的地位来说,是45。无论怎么样,都不可能让百位出现1,
个数加起来是highNum*100
3)、如果是32445,
对于它的高位来说,是32。一共有00100~00199,01100~01199,02100~02199,.....,31100~31199,一共是32*100个数。
对于它的地位来说,是45。一共有100~145,46个数。
个数加起来是(highNum+1)*100
所以总结起来就是
如果当前位为0,该位出现1的情况仅仅取决于高位
如果当前位为1,该位出现1的情况为高位*倍数 + 低位 + 1;
如果当前位大于1,该位出现1的情况仅仅取决于高位+1 乘以倍数;
所以结果就应该是对每个位求1出现的个数,加起来就是最终的结果。
Java AC
import java.util.Scanner; public class Main { /* * 1373 */ public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int a = scanner.nextInt(); int b = scanner.nextInt(); if (a == 0 && b == 0) { System.out.println(0); }else if (a == 0 || b == 0) { System.out.println(calCount(Math.max(a, b))); }else { int newA = Math.min(a, b); int newB = Math.max(a, b); int count1 = calCount(newA - 1); int count2 = calCount(newB); System.out.println(count2 - count1); } } } private static int calCount(int n) { int iCount = 0; int iFactor = 1; int iLowerNum = 0; int iCurrNum = 0; int iHigherNum = 0; while (n / iFactor != 0){ iLowerNum = n % iFactor; iCurrNum = (n / iFactor) % 10; iHigherNum = n / (iFactor * 10); switch (iCurrNum){ case 0: iCount += iHigherNum * iFactor; break; case 1: iCount += iHigherNum * iFactor + iLowerNum + 1; break; default: iCount += (iHigherNum + 1) * iFactor; break; } iFactor *= 10; } return iCount; } } /************************************************************** Problem: 1373 User: wzqwsrf Language: Java Result: Accepted Time:560 ms Memory:19036 kb ****************************************************************/
C++ AC
#include <stdio.h> int max(int x, int y){ return x > y ? x : y; } int min(int x, int y){ return x < y ? x : y; } int calCount(int n){ int iCount = 0; int iFactor = 1; int iLowerNum = 0; int iHigherNum = 0; int iCurrNum = 0; while((n / iFactor) != 0){ iLowerNum = n % iFactor; iCurrNum = (n / iFactor) % 10; iHigherNum = n / (iFactor * 10); switch (iCurrNum){ case 0: iCount += iHigherNum * iFactor; break; case 1: iCount += iHigherNum * iFactor + iLowerNum + 1; break; default: iCount += (iHigherNum + 1) * iFactor; break; } iFactor *= 10; } return iCount; } int main(){ int a, b; while(scanf("%d%d",&a,&b) != EOF){ if(a == 0 && b == 0){ printf("%d\n",0); }else if(a == 0 || b == 0){ printf("%d\n",calCount(max(a,b))); }else { int newA = min(a,b); int newB = max(a,b); int count1 = calCount(newA - 1); int count2 = calCount(newB); printf("%d\n",count2 - count1); } } return 0; } /************************************************************** Problem: 1373 User: wzqwsrf Language: C++ Result: Accepted Time:0 ms Memory:1020 kb ****************************************************************/