问题:

给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数。

例如:
N= 2,写下1,2。这样只出现了1个“1”。

N= 12,我们会写下1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12。这样,1的个数是5。

问题一:

写一个函数f(N),返回1到N之间出现1的个数,比如f(12)= 5。

解法一:

让我们首先想到的一个方法是:遍历1~N,统计每个数1出现的个数,相加便得到所有1的个数。

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
long long int Count(long long int n){
long long int count = ;
while(n){
count += (n % == )?:;
n = n / ;
}
return count;
}
int main()
{
long long int n,i,count;
while(scanf("%lld",&n) != EOF){
count = ;
for(i = ;i <= n;i++){
count += Count(i);
}
printf("%lld\n",count);
}
return ;
}

这个方法虽然很容易想,但是不是一个好方法。致命问题就是效率问题。如果给定的N很大,需要很长时间才能得出计算结果。

解法二:

分析的出规律。

<1>1位数情况

这个简单,如果N = 3,那么从1到3的所有数字:1,2,3,只有个位数出现1,而且只出现一次。可以发现,N是个位数时,N >=1,那么f(N)= 1;N = 0,f(N)= 0;

<2>2位数情况

<3>3位数情况

同理分析4位数,5位数。。。。。

设N = abcde ,其中abcde分别为十进制中各位上的数字。

如果要计算百位上1出现的次数,它要受到3方面的影响:百位上的数字,百位一下(低位)上的数字,百位一上(高位)上的数字。

如果百位上数字为0,百位上可能出现1的次数由更高位决定。比如:12013,则可以知道百位出现1的情况可能是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。可以看出是由更高位数字(12)决定,并且等于更高位数字(12)乘以 当前位数(100)。

如果百位上数字为1,百位上可能出现1的次数不仅受更高位影响还受低位影响。比如:12113,则可以知道百位受高位影响出现的情况是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。和上面情况一样,并且等于更高位数字(12)乘以 当前位数(100)。但同时它还受低位影响,百位出现1的情况是:12100~12113,一共114个,等于低位数字(113)+1。

如果百位上数字大于1(2~9),则百位上出现1的情况仅由更高位决定,比如12213,则百位出现1的情况是:100~199,1100~1199,2100~2199,...........,11100~11199,12100~12199,一共有1300个,并且等于更高位数字+1(12+1)乘以当前位数(100)。

 /*N = abcde 百位上数字是c
仅以求百位上出现1的情况为例。
*/
int count = ;
//百位上数字为0,百位上可能出现1的次数由更高位决定
if(c == ){
//等于更高位数字(ab)* 当前位数(100)
count += ab*;
}
//百位上数字为1,百位上可能出现1的次数不仅受更高位影响还受低位影响
else if(c == ){
//更高位数字(ab) * 当前位数(100) + 低位数字(de)+1
count += ab* + de + ;
}
//百位上数字大于1(2~9),百位上出现1的情况仅由更高位决定
else{
//(更高位数字+1(ab+1))* 当前位数(100)
count += (ab + ) * ;
}
 #include<stdio.h>

 long long int Count(long long int n){
//1的个数
long long int count = ;
//当前位
long long int Factor = ;
//低位数字
long long int LowerNum = ;
//当前位数字
long long int CurrNum = ;
//高位数字
long long int HigherNum = ;
if(n <= ){
return ;
}
while(n / Factor != ){
//低位数字
LowerNum = n - (n / Factor) * Factor;
//当前位数字
CurrNum = (n / Factor) % ;
//高位数字
HigherNum = n / (Factor * );
//如果为0,出现1的次数由高位决定
if(CurrNum == ){
//等于高位数字 * 当前位数
count += HigherNum * Factor;
}
//如果为1,出现1的次数由高位和低位决定
else if(CurrNum == ){
//高位数字 * 当前位数 + 低位数字 + 1
count += HigherNum * Factor + LowerNum + ;
}
//如果大于1,出现1的次数由高位决定
else{
//(高位数字+1)* 当前位数
count += (HigherNum + ) * Factor;
}
//前移一位
Factor *= ;
}
return count;
} int main(){
long long int a;
while(scanf("%lld",&a) != EOF){
printf("%lld\n",Count(a));
}
return ;
}

转载:http://blog.csdn.net/sjf0115/article/details/8600599

统计重1到n的正整数中1的个数的更多相关文章

  1. 学c语言做练习之​统计文件中字符的个数

    统计文件中字符的个数(采用命令行参数) #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[] ...

  2. HDU_2030——统计文本中汉字的个数

    Problem Description 统计给定文本文件中汉字的个数.   Input 输入文件首先包含一个整数n,表示测试实例的个数,然后是n段文本.   Output 对于每一段文本,输出其中的汉 ...

  3. 记-统计svn与git的log日志中的代码行变更

    任务要求 统计指定时间内,指定git地址与svn地址上的所有人员的代码行变更情况. 解决方案 最初为根据数据库中存储的所有git与svn地址来统计所有人员的提交代码行.之后由于库中存储的地址不全,改为 ...

  4. java统计指定目录中文件的个数和总的大小

    转: 统计指定目录中文件的个数和总的大小 package file; import java.io.File; import java.util.ArrayList; public class Fil ...

  5. 《剑指offer》-统计整数二进制表示中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 直观思路就是把二进制表示从右往左统计1的个数.直接想到移位操作来迭代处理.坑点在于负数的移位操作会填充1.有人贴出了逻辑移位 ...

  6. Java实现统计某字符串在另一个字符串中出现的次数

    面试时会经常考这样的题目,估计也不让使用正则表达式.还好这个算法还算简单,不过在草稿纸上写难免会出现运行异常,好吧,面试官赢了,乃们屌丝就实实在在的把代码码出来吧. 谢谢“心扉”对我代码bug的纠正, ...

  7. 统计无向图中三角形的个数,复杂度m*sqrt(m).

    统计无向图中三角形的个数,复杂度m*sqrt(m). #include<stdio.h> #include<vector> #include<set> #inclu ...

  8. 统计寄存器AX中1 的个数

    ;==================================== ; 统计寄存器AX中1 的个数 DATAS segment DATAS ends CODES segment START: ...

  9. JAVA实验--统计文章中单词的个数并排序

    分析: 1)要统计单词的个数,就自己的对文章中单词出现的判断的理解来说是:当出现一个非字母的字符的时候,对前面的一部分字符串归结为单词 2)对于最后要判断字母出现的个数这个问题,我认为应该是要用到ma ...

随机推荐

  1. hibernate中使用sql语句进行表链接查询,对结果集的遍历方法

    今天做了一个在hibernate中使用sql语句进行表链接查询的功能,得到的属性是来自两个表中的字段.下面对结果集遍历的方法进行记录. sql语句不写了.部分代码如下: List<Course_ ...

  2. ABP分层架构

    ABP分层架构 基于DDD的现代ASP.NET开发框架--ABP系列之3.ABP分层架构 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP ...

  3. python_基础学习_04_mysql库验证与安装(mysql-python,mysql.connector)

    验证python-mysql是否安装 1:python 2: import MySQLdb 安装步骤: 1.sudo apt-get install python-setuptools 2.sudo ...

  4. CSharp设计模式读书笔记(18):中介者模式(学习难度:★★★☆☆,使用频率:★★☆☆☆)

    中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互,中介者模式又称为 ...

  5. 转载使用Flurl制作可复用的分页组件

    使用Flurl制作可复用的分页组件 使用ASP.NET MVC查询时,一直使用MvcPaging组件,虽然需要自定义MvcPaging.Pager才能达到我想要的效果,但在没有较好的URL库时,还是这 ...

  6. PHP_零基础学php_3PHP函数、传参函数、默认参数、函数返回值

    <?php function say_hello() //无参数 { $name="tang"; echo "hello,".$name; echo &q ...

  7. ThinkPHP框架设计与扩展总结

    详见:http://www.ucai.cn/blogdetail/7028?mid=1&f=5 可在线运行查看效果哦 导言:ThinkPHP框架是国内知名度很高应用很广泛的php框架,我们从一 ...

  8. HTTP 错误500.19 -Internal Server Error

    原文:HTTP 错误500.19 -Internal Server Error HTTP 错误500.19 -Internal Server Error 错误代码 0x80070021 评论1 字号: ...

  9. java-list-remove()用法浅析 解决java list remove() 数据不对的问题

    在java中对list进行操作很频繁,特别是进行list启遍历,这些操作我们都会,也很熟悉,但是对java中list进行删除元素,remove list中的元素就不怎么熟悉了吧,可以说很陌生,是实际操 ...

  10. javascript中三目运算符和if else有什么区别

    javascript中三目运算符和if else有什么区别今天写了一个图片轮播的小demo,用到了判断先试了一下if else,代码如下:if(n >= count-1){n =0;}else{ ...