nbut 1407 1到n的数中 1出现的次数

  • [E] Meow star people learning numbers

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • Meow star people have a different way of counting. They use J、A、B、C……H、J to represent decimal system. A small cat had just learned it these days, she wrote it again and again, A, B, C, D,……AJ, AA, AB……。One day she wrote many numbers, for example, from A to AJJJ. She was tired of it, and want to calculate how many 'A'were in these numbers, for example there were 2 number of 'A'in number 'AJA'.


  • 输入
  • There are many cases, each contain a string N, means numbers from A to N(1<= strlen <= 9), see more details in hint please.
  • 输出
  • For each case, print the number of 'A'.
  • 样例输入
  • H
    AC
    
  • 样例输出
  • 1
    6
    
  • 提示
  • If N = AC, the numbers are A、B、C、D、E、F、G、H、I、AJ、AA、AB、AC. So we print 6.
  • 来源
  • 小白菜


http://acm.nbut.cn/Problem/view.xhtml?id=1407

题意 :

A、B、C、D、E、F、G、H、I  J  代表 1 2 3 4 5 6 7  8 9  0   输入一个字符串 长度小于等于9  问在这个字符串代表的数字n  从1 到 n  总共出现了多少个1 
比如 AC 代表13   则有 1 10 11 12 13  共有6个1  输出6




/*
思路:
  思路完全copy 于官方题解 菜比啊本人   要努力爆发额。。。。。。
官方解题地址:http://www.nbutoj.com/009/



题目的意思就是求从1到n,所有数字上出现1的个数。
当n为一位数的情况:
当n = 0,f(n) = 0; 当n >= 1, f(n) = 1.
当n为二位数的情况:
如果n = 13,所有数字中,个位和十位上都可能有1,那么分开讨论一下,个位出现1的次数有两次:1和11,十位出现1的次数有四次:10、11、12、13,
所以f(n) = 2+4 = 6.再看n = 23,十位出现1的次数有10次,从10到19,个位出现1的次数为1、11和21,所以f(n) = 3+10=13。
发现个位出现1的次数不仅和个位数有关,还和十位数有关,如果n的个位数大于等于1,则个位出现的次数为十位数的数字+1,
如果n的个位数为0,则个位数出现1的次数等于十位数的数字。而十位数上出现1的次数不仅和十位数有关,
还和个位数有关:如果十位数字等于1,则十位数上出现1的次数为个位数的数字加1,如果十位数大于一,则十位数上出现1的次数为10。
当n为三位数的情况:
如果n = 123,个位出现1的个数为13:1、11、21……91,101,111,121。十位出现1的个数为20:10~19,110~119,。百位出现1的个数为24:100~123
f(123) = 13 + 20 + 24 = 57。

现在计算一般的情况:假设n = abcde,这里a、b、c、d、e分别是十进制数n的各个位数上的数字。如果要计算百位上出现1的次数,它将受到三个因素的影响:
百位上的数字,百位以下的数字,百位以上的数字。
如果百位上的数字为0,则百位上可能出现1的次数由更高位决定,比如12013,则可以知道百位出现1的情况可能是100~199,1100~1199,2100~2199,…,11199~11199,,
一共有1200个。也就是由更高位数字(12)决定,并且等于更高位数字(12)×当前位数(100).
 如果百位上的数字是1,则百位上可能出现1的次数收到高位和低位的影响。
例如对于12113,受更高位影响,百位出现1的情况是100~199,1100~1199,2100~2199,…,11100~11199,一共1200个,和上面第一种情况一样,
等于更高位数字(12)×当前位数(100)。但它还受低位影响,百位出现1的情况是12100~12113,一共114个,等于低位数字(123)+1。
如果百位上数字大于1,则百位上可能出现1的次数也仅由更高位决定,比如12213,
则百位出现1的可能性为:100~199,1100~1199,2100~2199,…,11100~11199,12100~12199,一共有1300个,并且等于更高位数字+1(12+1)×当前位数(100)。
通过这样的总结归纳,就可以设计出较为高效的代码了。
*/
#include<iostream> 
using namespace std;  
int n,len; 
int cal(int n) 
{ 
    int count = 0; 
    int fac = 1; 
    int lower = 0; 
    int curr = 0; 
    int high = 0; 
    while(n / fac != 0) 
    { 
        lower = n - (n / fac) * fac; 
        curr = (n / fac) % 10; 
        high = n / (fac * 10); 
          
        switch(curr) 
        { 
            case 0: 
                count += high * fac; 
                break; 
            case 1: 
                count += high * fac + lower + 1; 
                break; 
            default: 
                count += (high+1)*fac; 
                break; 
        } 
        fac *= 10; 
    } 
    return count; 
} 
  
int main() 
{ 
    char ch[10]; 
    while(~scanf("%s",ch)) 
    { 
        len = strlen(ch); 
        n = 0; 
        for(int i = 0; i < len; i ++) 
        { 
            if(ch[i] == 'J') 
            { 
                n *= 10; 
            } 
            else
            { 
                n = n * 10 + (ch[i]-'A' + 1); 
            } 
        } 
        printf("%d\n",cal(n)); 
    } 
    return 0; 
}












   

你可能感兴趣的:(nbut 1407 1到n的数中 1出现的次数)