题目地址: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
****************************************************************/