zoukankan      html  css  js  c++  java
  • 几个一?

    一、题目

      给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。 要求: 写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数。例如 f(12) = 5。 在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少。

    二、设计思路

      思路来自于张欢龙的启发,就是将一个整数拆分,一位一位地求出“1”的个数,如451就是:

      45*1+1*1

    +4*10+1*10

    +0*100+1*100。

      先考虑个位,个位上数字0~9,总共出现过45个0~9,一个0~9有一个1,所以位45*1,而45个0~9外还有一个0~1,这时要再加上一个1;接着十位,每100个数里面均有*10到*19这10个出现1的数,所以十位也是0~9,但这里面的1要乘以10,4个0~9还多余一个0~5,所以也要加1,且乘以10;以此类推......

      如果某一位上是1,是不是情况就不一样了?如111,111情况如下:

     11*1+0+1

    +1*10+1+1

    +0*100+11+1

    ...

    +(m前面的十进制值*10m+m后面的十进制值+1(后面的值全为0的情况))

      就是当1出现时,这个多余的1的个数就为这一位后面的值。

      求f(N)=N的情况时,从2147483647开始向下逐一计算,时间过长,随便选了一个数即214748364,用前面的算法求出结果发现f(N)>N,所以正确的N一定比这个数小,所以从这开始计算。

    三、源代码

     1 //刘双渤,2015年6月3日
     2 //输入一个整数,输出出现1的个数
     3 #include <iostream>
     4 using namespace std;
     5 
     6 void main()
     7 {
     8     long num,rem,t,S;          //输入值,余数,十的倍数,一的总数
     9     long numS;
    10     cout<<"请输入一个整数:"<<endl;
    11     cin>>num;
    12 
    13     t = 1;
    14     S = 0;
    15     numS = num;
    16     while(numS != 0)
    17     {
    18         rem = numS % 10;
    19         numS = numS / 10;
    20         if(numS != 0)
    21         {
    22             S += numS * t;
    23         }
    24         
    25         if(rem > 1)
    26         {
    27             S += t;
    28         }
    29         else if(rem == 1)
    30         {
    31             S = S + num -numS * t* 10 - rem * t + 1;
    32         }
    33         t = t * 10;
    34     }
    35     cout<<"出现的“1”的个数为:"<<endl;
    36     cout<<S<<endl;
    37 
    38 
    39     for(long i = 214748364;i >= -214748364;i--)
    40     {
    41         t = 1;
    42         S = 0;
    43         numS = i;
    44         while(numS != 0)
    45         {
    46             rem = numS % 10;
    47             numS = numS / 10;
    48             if(numS != 0)
    49             {
    50                 S += numS * t;
    51             }
    52             if(rem > 1)
    53             {
    54                 S += t;
    55             }
    56             else if(rem == 1)
    57             {
    58                 S = S + i -numS * t* 10 - rem * t + 1;
    59             }
    60             t = t * 10;
    61         }
    62         if(S == i)
    63             break;
    64     }
    65     cout<<"满足条件的“f(N) =N”的最大的N是:"<<S<<endl;
    66 }
    View Code

    四、实验结果

      

    五、实验总结

     刚看到这个题目时,感觉很简单,然后就开始一个个值去算,用归纳法找规律,可越写发现情况越复杂,有点难!课上有人展示思路,下课再想,就有慢慢清晰,简单了起来。方法很多,却很需要这灵光一点,才能通透。

  • 相关阅读:
    SharePoint 2013 安装.NET Framework 3.5 报错
    SharePoint 2016 配置工作流环境
    SharePoint 2016 站点注册工作流服务报错
    Work Management Service application in SharePoint 2016
    SharePoint 2016 安装 Cumulative Update for Service Bus 1.0 (KB2799752)报错
    SharePoint 2016 工作流报错“没有适用于此应用程序的地址”
    SharePoint 2016 工作流报错“未安装应用程序管理共享服务代理”
    SharePoint JavaScript API in application pages
    SharePoint 2016 每天预热脚本介绍
    SharePoint 无法删除搜索服务应用程序
  • 原文地址:https://www.cnblogs.com/little-clever/p/4550579.html
Copyright © 2011-2022 走看看