【九度】题目1373:整数中1出现的次数(从1到n整数中1出现的次数)

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

你可能感兴趣的:(【九度】题目1373:整数中1出现的次数(从1到n整数中1出现的次数))