本帖最后由 Papaver_Flower 于 2012-03-07 10:54:44 编辑

解决方案 »

  1.   

    运行结果:
    0--13生成的字符串:012345678910111213
    期中1匹配次数:6次源码:
    import java.util.regex.*;
    public class PapaverFlower { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    PapaverFlower pf =  new PapaverFlower();
    //传递一个整数13
    System.out.println("期中1匹配次数:"+pf.getNumberOne(13)+"次");
    }

    //输入要匹配到整数
    public int getNumberOne(int num){
            
    int mapSum = 0;//定义一个计数器
    String regex = "[1]";//正则
    String textStr = "";

    //通过传递过来的数,生成字符串
    for(int i = 0; i <= num; i ++){
    textStr += i;
    }
    System.out.println("0--"+num+"生成的字符串:"+textStr);
    //使用正则表达式,查找(没有便利数组,逐个获取)
    Matcher m = Pattern.compile(regex).matcher(textStr);
    while(m.find()){
    ++ mapSum;
    }
    return mapSum;
    }}
      

  2.   

    如果上面的有便利
    那么直接用
    "012345467891011121314".split("1").length();
      

  3.   

    规律
    10^n里包含 n*10^(n-1)+1个1
    也就是 10的n次方 包含 n乘以10的n-1次方+1 个1
      

  4.   

    也经知道这个规律了,接下来就是分析一个数的组成
    首先看看规律 10^n里包含 n*10^(n-1)+1个1

    1 包含  1个1
    10 包含 2个1
    100 包含 21个1
    1000 包含 301个1
    10000 包含 4001个1

    举例说明,取100和1000之间,知道100和1000相差301-21=280个1
    而我们知道100-200之间,百位数是1有100个,所以去掉1开头的数 280-100=180
    而200-999每100个数,它们的1的个数是一样的,所以它们之间每100个数有 180/9 = 20 个1
    同样的,可以知道2000-9999它们之间每1000个数有 (4001-301-1000)/9 = 300 个1
    20-99它们之间每10个数有 (21-2-10)/9 = 1 个1

    这样,一个数,比如 abc=a*100+b*10+c,分别计算它的每个位数a,b,c所包含的1就可以了
      

  5.   

      本来觉得很近了很快就写出来了,结果到现在还没有。
      我的进展——我分析了1出现的次数:
      1——9: X1(也就是01) 1
      1——99: X1 1X (1*10)+10
      1——999: 1XX 1X X1 (1*10+10)*10+100
      1——9999: 1XXX 1XX 1X X1 ((1*10+10)*10+100)*10+1000
      即每次都是上面高手说的函数10的N次方里面有(N*10的N-1次方个+1)个1。
      中午吃饭的时候我认为只剩下了两个思路。
      第一就是把数拆开,分成几个相加的数,这个拆的方法我试了好几种都觉得不完美,现在还在试。
      第二,其实也是拆,就是每次求余,把每一个数写出来,再根据数的位数进行计算。比如:13可以拆为1和3,因为它是两位数,有根据X1,1X的方法,可以计算为1*(1+1)+1*(3+1)=6,也就是XY的一的个数为:1*(X+1)+1*(Y+1)这样的话也就有特例,如果是几十的数而不是十几的数比如23,我们就要1*(2+1)+10=13了,几十的就成了1*(X+1)+10。如果这样分析我们似乎还要用第一种方法拆数,才可以做最后计算。
      现在分析到三位数依然要考虑很多东西,正在解决中
      

  6.   

    没有花很多时间想,但我总觉得用递归可能会更好些,把本级整数部分跟其它余数分开来算,比如对于一个3位数:abc我的想法是分解为:
    100:直接公式计算出来(n*10^(n-1)+1)
    101~199:直接公式计算出来(公式没研究)
    201~(a)00:直接公式计算出来 (a-1)*(跟前一个公式的区别是少了整整 100 个1)
    a00~abc:递归调用来计算bc的这里面免不了要些if判断。
      

  7.   

    其实真正的高手是 qybao(阿宝),这哥们一发飙,最后直接给你个数学公式就交差了。
      

  8.   

      往常,在一些群里我看调侃和玩闹的人居多一问到问题就哑火了。我建立了一个群,曾经给你发过消息,你没有回,我想拉一些真正的专注技术的人聚集在一起。把QQ短消息给我吧。我拉你进去。
      OK,回归主题。你做做试试看啊,十五楼的哪一组计算我也看得出来用递归,不过中间有很多需要判断的地方,复杂的无法处理。做做试试啊。
      

  9.   

    import java.util.Scanner;public class testContainOne {
    public static void main(String a[]){

    Scanner sc=new Scanner(System.in);
    int read=sc.nextInt();
    String in=new Integer(read).toString();
    char readIn[]=in.toCharArray();
    //count(readIn);
    int sumsum=count(readIn);
    System.out.println(sumsum);
    }
    public static int count(char a[]){
    int sum=0;
    double c=a.length;
    int[] b=new int[a.length];
    for(int i=0;i<a.length;i++){
    b[i]=a[i]-'0';
    }

    for(int  i=0;i<Math.pow(2.0, c);i++){
    String  er=parse(i,a.length);
    char bufferchar[]=er.toCharArray();

    int countOne=0;
    int local=1;
    for(int x=0;x<bufferchar.length;x++){
    if((bufferchar[x]-'0')==1)
    countOne++;
    else{
    local*=b[x];
    }
    }
    if(countOne==bufferchar.length)
    sum+=bufferchar.length;
    else
        sum+=local*countOne;
    }
    return sum;
    }
    public static String parse(int x,int y){
    StringBuilder   sb=new StringBuilder();

    int g=0;

    for(int i=x;;i=i/2){
    if(i/2==0){
    sb.append(i%2);
    break;
    }
    sb.append(i%2);
    }
    for(int i=sb.length();i<y;i++){
    sb.append(0);
    }

    return sb.reverse().toString();
    }

    }
      

  10.   

    我原来以为数是便利出来的呢
    这回这个不是便利的,是嵌套递归
    运行结果:0到100共有21个1
    源码:
    public class PapaverFlower2 {
    String AddNumber ="";
    static int saveNum = 0;
    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    //输入你要测试的数字
    saveNum = 100;
    new PapaverFlower2().doNest(saveNum);
    } public void doNest(int num){
    AddNumber += ""+num;
    num -= 1;
    if(num < 0){
    System.out.println("0到"+saveNum+"共有"+(AddNumber.split("1").length - 1)+"个1");
    }else if(num >=0) {
    doNest(num);
    }

    }}
      

  11.   


    给你一段代码吧public class Test {    
        public static void main(String[] args) throws Throwable {
            int num = 13; //测试数据,可以自己修改
            System.out.println(countOne(num)); //打印结果
        }    public static int countOne(int num) { //计算1的个数
            if (num < 1) return 0;
            int org = num, count = 0, pow = 1, dig = 0, m = 0;
            //pow代表10的n次方,dig代表n,m代表每位的数字
            while (num > 0) { //从个位开始循环取每位数字
                m = num % 10; //获取每位数字
                if (m > 0) { //如果该数字不为0
                    count += dig * pow / 10 + 1; //首先用公式计算1的个数 --A
                }
                if (m == 1) { //如果该位数字为1,则此时最高位为1的个数就是原始数%10的n次方
                    count += org % pow;
                } else if (m > 1 && dig > 0) { //如果该位数字不为1,并且是10位数以上
                    count += pow - 1; //首先之前说明例子中的100-200之间的最高位为1的个数pow
                                      //这里为何要-1,因为在A的地方,100已经被我们计算过一次了
                    count += (m-1)* dig * pow / 10; //然后这里就是之前例子中的200-999之间的
                                                           //每100个数相差的1的个数
                }
                
                num /= 10; //原数右移,为了取最低位的数字
                pow *= 10; //10的n次方增加,因为没计算一次,位数相当于左移,即从个位到百位等等
                dig++; //n次方的n增加
            }
            return count; //返回值
        }
    }
      

  12.   


      虽然没有明着遍历,递归每次调用这个方法,num都会减1,和遍历一样。
      谢谢。
      

  13.   

    这个题应该改成 输入两个整数 a,b(a>b)计算从b到a所有的整数中b出现了多少次.
      

  14.   

    想了个思路,不知道对不对,大家说说看!
    a : x 位整数
    b : y 位整数 
    n = x- y;
    int sum +=0;
    for(int i =1;i< n-1 ;i++)
    {
         第一种情况: 整数b在构成后数字的前面 例如  12,构成 121,122,125等
     for(int j = 1; j <= i;j++)
     {
            sum += Math.paw(10,j);
         }
         第二种情况: 整数b在构成后数字的中间 例如 12 构成  112,212,312等 有重复的情况,但是必须考虑出现重复的数字 例如 1212 12112 121212等数字
    }
    接着考虑 有b数字构成x位数的情况
    情况和上面的一样两种:不过要考虑构成后数字与A数字的大小
      
      

  15.   

    严重损伤我所剩不多的脑细胞啊,经过不懈努力,终于把递归的写出来了,为了保险起见,跟前面大牛qybao的做了核对。程序如下:public class 整数中1出现次数 {    /**
         * @param args
         */
        public static void main(String[] args) {
            System.out.println("1=" + countOne(1) + " " + ldhCount(1));
            System.out.println("9=" + countOne(9) + " " + ldhCount(9));
            System.out.println("13=" + countOne(13) + " " + ldhCount(13));
            System.out.println("20=" + countOne(20) + " " + ldhCount(20));
            System.out.println("99=" + countOne(99) + " " + ldhCount(99));
            System.out.println("100=" + countOne(100) + " " + ldhCount(100));
            System.out.println("101=" + countOne(101) + " " + ldhCount(101));
            System.out.println("109=" + countOne(109) + " " + ldhCount(109));
            System.out.println("113=" + countOne(113) + " " + ldhCount(113));
            System.out.println("120=" + countOne(120) + " " + ldhCount(120));
            System.out.println("121=" + countOne(121) + " " + ldhCount(121));
            System.out.println("199=" + countOne(199) + " " + ldhCount(199));
            System.out.println("209=" + countOne(209) + " " + ldhCount(209));
            System.out.println("213=" + countOne(213) + " " + ldhCount(213));
            System.out.println("220=" + countOne(220) + " " + ldhCount(220));
            System.out.println("1000=" + countOne(1000) + " " + ldhCount(1000));
            System.out.println("1001=" + countOne(1001) + " " + ldhCount(1001));
            System.out.println("1009=" + countOne(1009) + " " + ldhCount(1009));
            System.out.println("1010=" + countOne(1010) + " " + ldhCount(1010));
            System.out.println("1013=" + countOne(1013) + " " + ldhCount(1013));
            System.out.println("1099=" + countOne(1099) + " " + ldhCount(1099));
            System.out.println("1100=" + countOne(1100) + " " + ldhCount(1100));
            System.out.println("1110=" + countOne(1110) + " " + ldhCount(1110));
            System.out.println("1111=" + countOne(1111) + " " + ldhCount(1111));
            System.out.println("1313=" + countOne(1313) + " " + ldhCount(1313));
            System.out.println("9999=" + countOne(9999) + " " + ldhCount(9999));
            System.out.println("13913=" + countOne(13913) + " " + ldhCount(13913));
            System.out.println("913913=" + countOne(913913) + " " + ldhCount(913913));
            System.out.println("3913913=" + countOne(3913913) + " " + ldhCount(3913913));
            System.out.println("13913913=" + countOne(13913913) + " " + ldhCount(13913913));
            System.out.println("113913913=" + countOne(113913913) + " " + ldhCount(113913913));
            System.out.println("213913913=" + countOne(213913913) + " " + ldhCount(213913913));
            System.out.println("313913913=" + countOne(313913913) + " " + ldhCount(313913913));
            System.out.println("413913913=" + countOne(413913913) + " " + ldhCount(413913913)); // 似乎前者溢出了
            System.out.println("513913913=" + countOne(513913913) + " " + ldhCount(513913913)); // 似乎前者溢出了
            System.out.println("713913913=" + countOne(713913913) + " " + ldhCount(713913913)); // 似乎前者溢出了
            System.out.println("913913913=" + countOne(913913913) + " " + ldhCount(913913913)); // 似乎前者溢出了
           
        }    /**
         * 我的基于递归的算法
         */
        public static int ldhCount(int num) {
            if (num < 10) { // 个位数            
                return (num > 0) ? 1 : 0;
            } else { // 非个位数
                int sum = 0; // 记录汇总数
                int n = String.valueOf(num).length() - 1; // 计算当前数值的数量级
                int p = (int) Math.pow(10, n); // 本数量级 10^n 的值
                int a = num / p; // 首位数字是啥
                int y = num - a * p; // 余数
                int up = ldhCount(y); // 迭代计算低一个数量级的1的个数
                int tmp = n * ((int) Math.pow(10, n - 1)); // 该公式所计算的值经常用,先放起来
                            
                sum =  tmp; // 从 000~999 的1的个数
                
                /* 下面这段if中的某些语句可以抽出来公用,但是这样会导致看不清楚思路,我就保留原样了 */
                if (a == 1) {
                    sum += y + 1 + up; // 1000 ~ 1bcd中,首位字符出现1为(y+1)次,其它字符(?000 ~ ?bcd)出现为up(迭代)次
                } else if (a == 2) {
                    sum += p + tmp; // 从 1000~1999,首位字符出现1为(10^n)次,其它字符用公式tmp(000~999)
                    sum += up; // 从 2000~2bcd
                } else {
                    sum += p + tmp; // 从 1000~1999,首位字符出现1为(1000)次,其它字符用公式tmp(000~999)
                    sum += (a - 2) * tmp;// 从 2000~(a-1)999,实际上就是 a-2 次tmp(000~999),因为首位数1和首位数a的情况已经另行处理了
                    sum += up; // 从 a000~abcd
                }            return sum;
            }
        }    /**
         * 大牛qybao基于循环(其实应该是递推)的算法
         */
        public static int countOne(int num) { //计算1的个数
            if (num < 1)
                return 0;
            int org = num, count = 0, pow = 1, dig = 0, m = 0;
            //pow代表10的n次方,dig代表n,m代表每位的数字
            while (num > 0) { //从个位开始循环取每位数字
                m = num % 10; //获取每位数字
                if (m > 0) { //如果该数字不为0
                    count += dig * pow / 10 + 1; //首先用公式计算1的个数 --A
                }
                if (m == 1) { //如果该位数字为1,则此时最高位为1的个数就是原始数%10的n次方
                    count += org % pow;
                } else if (m > 1 && dig > 0) { //如果该位数字不为1,并且是10位数以上
                    count += pow - 1; //首先之前说明例子中的100-200之间的最高位为1的个数pow
                                      //这里为何要-1,因为在A的地方,100已经被我们计算过一次了
                    count += (m - 1) * dig * pow / 10; //然后这里就是之前例子中的200-999之间的
                                                       //每100个数相差的1的个数
                }            num /= 10; //原数右移,为了取最低位的数字
                pow *= 10; //10的n次方增加,因为没计算一次,位数相当于左移,即从个位到百位等等
                dig++; //n次方的n增加
            }
            return count; //返回值
        }
    }
    【计算结果】
    1=1 1
    9=1 1
    13=6 6
    20=12 12
    99=20 20
    100=21 21
    101=23 23
    109=31 31
    113=40 40
    120=53 53
    121=55 55
    199=140 140
    209=141 141
    213=146 146
    220=152 152
    1000=301 301
    1001=303 303
    1009=311 311
    1010=313 313
    1013=320 320
    1099=420 420
    1100=422 422
    1110=444 444
    1111=448 448
    1313=780 780
    9999=4000 4000
    13913=10100 10100
    913913=560100 560100
    3913913=3360100 3360100
    13913913=14274014 14274014
    113913913=108187928 108187928
    213913913=274274014 274274014
    313913913=354274014 354274014
    413913913=4777285  434274014  // 似乎前者溢出了
      

  16.   

    客观地说,我跟qybao的算法思路并不一样(不是指递归和循环本身的差异,而是指如何计算1的过程)。
    当然的,他的算法思路从性能上而言比我的好多了。我的算法主体思路其实就在20楼。总的来说,是一种收获,嗯。
      

  17.   

    其实我最开始以为应该是我溢出了,因为我用了幂运算,而qybao并没有用幂运算。
    估计是这句话导致的溢出:
    count += (m - 1) * dig * pow / 10
    因为是先乘再除了,修改的话大概是:
    count += (m - 1) * dig * (pow / 10)
    不过溢出并不是问题,就算最了不起无非是改为long而已。
    而用了幂运算的计算代价肯定是要高的,qybao则巧妙的一直利用pow *= 10这种方式逐步实现幂运算的类似效果。
      

  18.   

      阿宝真的很厉害,我把他写的打印了一份,准备好好看看。到现在为止,pow和dig这两个变量,我依然觉得很难控制。对那段代码着实感觉陌生,看的不是很轻松,也很不透彻。
      

  19.   

      昨天一个人给我的建议:给大家参考下。
      “这个题目有个简单的方法”
      “每一位,当其不是首位的时候,出现的次数就是10的整数倍,而1出现的频率是1/10”
      “计算0-10^n-1时,1的个数,等于非首位字符个数/10再加上首位中的1出现的次数”
      “而首位的出现次数,也可以用类似的统计方法来计算”
      “最终计算的时候,例如0-3361,可以分解为0-999; 1000-2999;3000-3299;3300-3359;3360-3361”
      “第一部分是从0-10^n-1,剩余部分,第一部分是从10^n-1到M*10^n,其余部分的分块等于除首位的有效位的个数(或+1)”
      “我说的这个方法关键是概率,也可以按照其他方法来划块.”
      

  20.   

    转成字符串,然后split(‘1’)-1   不行吗?
      

  21.   

    对于自然数N,设第x数位的值为d[x],共有m位数字,该位为1时所有可能的排列数为c[x],级数为p[x],第x数位左部的数为h[x],第x数位的右部的数为t[x],“1出现的次数”为OneSum
    如N=123456,x=3,d[3]=4,p[3]=100, h[3]=123, t[3]=56

    d[x]==0时, c[x]=h[x]*p[x];
    d[x]==1时,c[x]=h[x]*p[x]+t[x]+1;
    d[x]>1时,c[x]=(h[x]+1)*p[x];
               m
    而OneSum= 总和: c[x]
              x=1
      

  22.   


    当然不行,你试试 11111 或者 1001  或者 100 等等.楼主说不遍历,那是胡扯,不遍历,谁知道那是什么东西,关键是怎么遍历的问题.
    比较简单的方法,参考String的split方法, 把那些数字拼成一个StringBuilder,去正则匹配1 ,然后进行计数就完了.
      

  23.   


    public class FindOne
    {
    public static void main(String[] args)
    {
    System.out.println(count(13));
    } public static int count(int limit)
    {
    int count = 0;
    for (int i = 0; i <= limit; i++)
    {
    count = count + countOne(i);
    }
    return count;
    } public static int countOne(int n)
    {
    int count = 0;
    if (n == 1)
    {
    count++;
    } else
    {
    if (n % 10 == 1)
    {
    count = count + 1 + countOne((int) n / 10);
    } else
    {
    count = count + countOne((int) n / 10);
    }
    }
    return count;
    }
    }
      

  24.   

    上面代码有误,更新如下public class FindOne
    {
    public static void main(String[] args)
    {
    System.out.println(count(13));
    } public static int count(int limit)
    {
    int count = 0;
    for (int i = 0; i <= limit; i++)
    {
    count = count + countOne(i);
    }
    return count;
    } public static int countOne(int n)
    {
    int count = 0;
    if(n==0)
    {
    return 0;
    }
    if (n == 1)
    {
    return 1;
    } else
    {
    if (n % 10 == 1)
    {
    count = count + 1 + countOne((int) n / 10);
    } else
    {
    count = count + countOne((int) n / 10);
    }
    }
    return count;
    }
    }
      

  25.   

    #include <iostream>
    #include <math.h>using namespace std;long calLength(long n);
    long countOnes(long n);long main()
    {
    long counter = 0;
    long num;
    cin >> num;
    long length = calLength(num);
    long base = 1;
    for (long i = 0; i < length - 1; i ++)
    {
    base *= 10;
    }
    cout << "Base = : " << base << endl;
    while (num > 0)
    {
    long tmp = num;
    long btmp = base;
    long one = 0; if (num / base == 0)
    {
    base /= 10;
    } while ((one = tmp / btmp) != 1 && tmp > 10)
    {
    tmp %= btmp;
    btmp /= 10;
    } if (tmp < 10 && tmp >= 1)
    {
    counter ++;
    num /= 10;
    num *= 10;
    num --;
    continue;
    } while (tmp >= 10 && tmp / btmp == 1)
    {
    counter += countOnes(num);
    num --;
    tmp --;
    }
    }
    cout << counter << endl;
    return 0;
    }long calLength(long n)
    {
    long length = 0;
    while (n)
    {
    n /= 10;
    length ++;
    }
    cout << "Length = : " << length << endl;
    return length;
    }long countOnes(long n)
    {
    long counter = 0;
    while (n)
    {
    if (n % 10 == 1)
    counter ++;
    n /= 10;
    }
    return counter;
    }这个可以不
      

  26.   

    今天培训没事时候,又拿出来这个题做了下。找到了新的规律
    可以更方便解决
    源码:
    int num = 88,saveNum = 1,countNum = 0;
    while(num!=0)
    {
    num/=10;
    countNum +=(num+1)*saveNum;
    saveNum*=10;
    }
    System.out.println(countNum);
    编码思路:
    ****************************************
    根据重复的数量级进行计算
    对2238验证
    8重复的是个位上的数量级 所以不变化
    3重复的是十位上的数量级 所以每十个变换一次
    2重复的是百位上的数量级 所以每百个变化一次
    2重复的是千位上的数量级 所以每千个变化一次--个位【从十位往上算】
    对于个位上的数量级  重复次数是个位除外 前n位的去零数
    8 重复223+1次       所以有224*1--十位【从百位向上算】
    3 重复22+1次        所以有23*10--百位【从千位本身向上算】
    2 重复2+1次         所以有3*100--千位【从万位本身向上算】
    2 重复1次           所以有1*1000
    *******************
    88验证
     (8+1)*1 + 1*10
    =19
    *******************
    295验证
     (29+1)*1 + (2+1)*10 + (1)*100
    =30+30+100
    =160
    *******************
    322验证
     (32+1)*1 + (3+1)*10 + (1)*100
    =33+40+100
    =173
    *******************
    999验证
      (99+1)*1 + (9+1)*10 + (1)*100
    =100+100+100
    =300
    224验证
      (22+1)*1 + (2+1)*10 + (1)*100
    =23+30+100
    =153     
    100验证
      (10+1)*1 + (1+1)*10 + (1)*100
    =11+20+100
    =131
    bug:对于0 需要判读比如100
    希望读懂思路以后 自己加上
    对于详细思路可以加群
    一起讨论:5307397
    如有疏漏望指点
      

  27.   


    嗯 是的 有的地方会有bug  所以请大家研究下我的方法可行不
    就你理我了 谢谢 wuuw
      

  28.   

    不可行,你的程序上来就 num/=10; ,已经把个位数丢失了,咋能可行的了另外就是完全没看懂你的算法在说啥 =_=
      

  29.   

    这就是最关键的部分啊,你没发现之前qybao的代码那么复杂,其实都是为了处理 0 和 1 的情况 =_=摘录片段:            if (m > 0) { //如果该数字不为0
                    count += dig * pow / 10 + 1; //首先用公式计算1的个数 --A
                }
                if (m == 1) { //如果该位数字为1,则此时最高位为1的个数就是原始数%10的n次方
                    count += org % pow;
                } else if (m > 1 && dig > 0) { //如果该位数字不为1,并且是10位数以上
      

  30.   

    你详细点介绍下,然后再探讨咯。建议就用 abcd 这样的数字来举例,另外别忽略了0和1的处理,因为这两个最关键。
      

  31.   

    public class Test {
    public static void main(String[] args) {
    int n = 1010;
    int result = 0;
    int i = 1;
    boolean flag = true;
    if (n > 0) {
    while (i < n + 1) {
    String text = new Integer(i).toString();
    if (text.indexOf("1") != -1) {
    result++;
    System.out.print(text + " ");
    }
    if (flag) {
    i += 9;
    flag = false;
    } else {
    i += 1;
    flag = true;
    }
    }
    }
    System.out.println("\n共出现了:" + result);
    }
    }
      

  32.   

    就是个数字游戏而已,找好规律直接编程就行了,是数学问题,不是算法问题
    #include <stdio.h>
    #include <stdlib.h>int main(int argc, char *argv[])
    {
        if (2 != argc) {printf("usage:[%s] num\n", argv[0]); return -1;};
        int num = abs(atoi(argv[1]));
        int count = 0;
        while (10 <= num)
        {
            int bits = 0, numtmp = num, curint = 1;;
            while(1)
            {
                curint *= 10;
                ++bits;
                if (10 >(numtmp = numtmp/10))
                    break;
            }
            if (numtmp > 1)
                count += curint;
            else
                count += ((num%curint) + 1);
            count += bits*((curint/10)*(num/curint));
            num = num%curint;
        }
        if (num >= 1)
            ++count;
        printf("%d\n", count);
        return 0;
    }
      

  33.   

    好 我把思路 说一下
    对于abcd这个数
    公式:(abc+1)*1+(ab+1)*10+(a+1)*100+(1)*1000

    依次类推。
    对应:2234
          (223+1)*1+(22+1)*10+(2+1)*100+(1)*1000
        =224+230+300+1000
        =1754

    编程思路:
    按照个位、十位、百位、千位……计算首先个位:例如88在下面表中可以看到,
              88一直竖着向上 会有8+1个1(8来自十位上的数,8 7 6 ... ...)
               
    之后十位:十位上,要看88 这个数没有百位。因为没有百位。
             所以是(0+1)*10
    88验证
     (8+1)*1 + 1*10
    =19
    *******************
    295验证
     (29+1)*1 + (2+1)*10 + (1)*100
    =30+30+100
    =160
    *******************
    322验证
     (32+1)*1 + (3+1)*10 + (1)*100
    =33+40+100
    =173
    对应理解数字表:
    01  02  03  04  05  06  07  08  09  10
    11  12  13  14  15  16  17  18  19  20
    21  22  23  24  25  26  27  28  29  30
    31  32  33  34  35  36  37  38  39  40
    41  42  43  44  45  46  47  48  49  50
    51  52  53  54  55  56  57  58  59  60
    61  62  63  64  65  66  67  68  69  70
    71  72  73  74  75  76  77  78  79  80
    81  82  83  84  85  86  87  88  89  90
    91  92  93  94  95  96  97  98  99  100101  102  103  104  105  106  107  108  109  110
    111  112  113  114  115  116  117  118  119  120
    121  122  123  124  125  126  127  128  129  130
    131  132  133  134  135  136  137  138  139  140
    141  142  143  144  145  146  147  148  149  150
    151  152  153  154  155  156  157  158  159  160
    161  162  163  164  165  166  167  168  169  170
    181  182  183  184  185  186  187  188  189  190
    191  192  193  194  195  196  197  198  199  200
    201  202  203  204  205  206  207  208  209  210
    211  212  213  214  215  216  217  218  219  220
    221  222  223  224  225  226  227  228  229  230
      

  34.   

    规律就是我们取一个最高位的整数,比如2123就取2000,2000的话有多少个1呢?两种情况
    1.如果最高位大于1,那当最高位为1的时候后面的数每一位有10中可能,一共就有3位,也就是1000个1
    2.如果最高位等于1,那就是这个数除以1000的余数然后加自身的1,比如1001,那就是1+1=2,1011那就是11+1=12
    这是最高位的情况,同样,当低位为1的时候算组合,由于最高位有限制,所以不可能有10种,所以低位为1的时候的组合数量为最高位的值*其他位的可能,2000的话次高位为1的时候就有2*10*10共两百种可能,其他的为以此类推,然后递归下去就得到答案了算法可能有很多,我的可能是其中一种,这里写了个一定能算出正确答案的傻瓜式代码供大家测试,申请的内存有限,不要让数值太大,懒得改了#include <stdio.h>
    #include <string.h>
    #include <stdlib.h>int main(int argc, char *argv[])
    {
        if (2 != argc) {printf("usage:[%s] num\n", argv[0]); return -1;};
        int num = abs(atoi(argv[1]));
        char *buff = malloc(1000000);
        memset(buff, 0, 1000000);
        char *guard = buff;
        int i = 0;
        for (; i<=num; ++i)
        {
            guard += sprintf(guard, "%d", i);
        }
        int count = 0;
        for (guard=buff; '\0'!=*guard; ++guard)
        {
            if ('1' == *guard) ++count;
        }
        printf("%d\n", count);
        return 0;
    }
      

  35.   

    0 1  的问题解决了源码:要是运行不对请留言或者加qq184172133 
    public class XiaoFuNumberGetOne { /**
     * @param args
     * 
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    int num = 11113,saveNum = 1,countNum = 0,lastNum=0,numCopy = num,oneCl = 1;
    while(num!=0)
    {
    lastNum = num%10;

    //System.out.println(lastNum);

    num/=10; if(lastNum == 0){
    countNum +=(num)*saveNum;
    }else if(lastNum == 1){
    countNum += num * saveNum + numCopy%(oneCl) + 1;
    }else{
    countNum +=(num+1)*saveNum;
    }
    oneCl*=10;
    saveNum*=10;
    }
    System.out.println(countNum); }}
      

  36.   

    totals[10]={0};//依次保存从0到9, 10个数字出现的次数//
    for ( int num = 0; num <= setting_num; num++ )
    {
         string str = int2string( num );
         for ( int i = 0; i < str.length(); i++ )
         {
             int index = (int)(str[i]-'0');         
             totals[index]++;
         }
    }