题目如下:

The task is simple: given any positive integer N, you are supposed to count the total number of 1's in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1's in 1, 10, 11, and 12.

Input Specification:

Each input file contains one test case which gives the positive N (<=230).

Output Specification:

For each test case, print the number of 1's in one line.

Sample Input:

12

Sample Output:

5

对于此类问题,应当从找一般化的规律为主,而不应当试图推导排序组合的数学表达式。

这道题目的难点在于每一位都有出现1的可能,例如100,010,001,110等,如果按照排序组合考虑,因为要计数1的个数,因此对于1的个数不同,要分别对待,这将会是很棘手的问题。

如果换个思路,从每一位入手,研究每一位的规律,则会使得问题简单得多,这种研究方法是科学的,因为每一位都考虑了自己的1,那么合起来对于多个1的问题就自然考虑进来了,例如N=12时,我们分别考虑下面的情况:

个位出现1的有1,11,十位出现1的有10,11,12,我们看到,对于11这种多个1的情况,正好计算了两次,对于多位也是这个道理。

下面我们从一个5位数入手,研究百位不同时,百位为1的所有情况的计算:

我们以12045、12145、12245为例。
12045:
百位为0,那么高位不变低位部分无法产生类似1XX的数字,因此考虑高位,注意到只要比当前值小就可以,因此可选择:00100-00199,01100-01199 ... 11100-11199 一共12*100=1200,观察到等于比当前高位的数字*100。
也就是:高位数字*100,注意到这个100和当前考虑的位有关,百位为100,从低位为第1位开始计算第x位为10的x次方,也就是说对不同的位这个100应该换成相应的值。

12145:
百位为1,那么高位不变,低位从100-145都可以,共45+1=46个,高位仍然可以产生百位为0时的变化,共1200+46+1246种
也就是:高位数字*100 + 低位数字+1
12245:
对于百位大于1的情况,我们只需要考虑高位即可列全所有,从00100-00199到12100-12199,共13*100=1300
也就是:(高位数字 + 1)*100

解决了这个问题,下面要解决的是取出高位数、当前位、低位数的问题,我们以6位数abcdef取出百位为例:

对于abcdef,设因数factor=100,即要取出百位d
按照常规方法,百位 = abcdef / factor % 10 = abcd % 10 = d
高位数字 = abcdef / factor / 10 = abc
低位数字 = abcdef - abcd00 = ef
而abcd00 = (abcdef / factor) * factor = abcd00
所以低位数字 = abcdef - ( abcdef / factor ) * factor

这时候,factor就是前面我们要找的从低位开始算的10的x次方,因此编写代码变得简单,只需要从低位开始,也就是factor从1开始,每次乘以10,直到超出当前值,此时N/factor=0,停止运算。

代码如下:

#include <iostream>
#include <stdio.h>using namespace std;int compute(int N){int factor = 1;int low = 0;int high = 0;int now = 0;int cnt = 0;while(N / factor != 0){now = (N / factor) % 10;high = N / factor / 10;low = N - (N / factor) * factor;switch(now){case 0:cnt += high * factor;break;case 1:cnt += high * factor + low + 1;break;default:cnt += (high + 1) * factor;}factor *= 10;}return cnt;}int main()
{int N;while(scanf("%d",&N) != EOF){cout << compute(N) << endl;}return 0;
}

转载于:https://www.cnblogs.com/aiwz/p/6154130.html

1049. Counting Ones (30)相关推荐

  1. PAT甲级1049 Counting Ones (30 分):[C++题解]统计1的个数、数位统计

    文章目录 题目分析 题目链接 题目分析 来源:PAT网站 分析: 以数字abcdefg这个7位数字为例,说一下本题的思路. 1)数字1在每一位出现的次数. 2)以第d位为例,第d位的取值可以分为3种情 ...

  2. 1049 Counting Ones (30 分)【难度: 难 / 知识点: 分治 / DP】

    https://pintia.cn/problem-sets/994805342720868352/problems/994805430595731456 方法一: 找规律,分治做法. //0-999 ...

  3. pat1049. Counting Ones (30)

    1049. Counting Ones (30) 时间限制 10 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The task ...

  4. pat1004. Counting Leaves (30)

    1004. Counting Leaves (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A fam ...

  5. PAT甲级1004 Counting Leaves (30分):[C++题解]树、邻接表存储树、dfs遍历树

    文章目录 题目分析 题目链接 题目分析 题意重述:一棵树,求每一层的叶子节点数目. 分析 构造树,使用邻接表来存(相当于存储有向图). 需要一个头结点数组h[N],然后每个头节点往外形成一个单链表e[ ...

  6. 1004. Counting Leaves (30)

    时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A family hierarchy is usually pr ...

  7. 1049 Counting Ones

    1. 这一题起初我用递归的方式,还写了一个数整数有多少个1的函数,OneNum[i] = OneNum[i-1]+countOne(i);毫不意外地出现了段错误,也就是递归调用的次数太多. 2. 看了 ...

  8. 1004 Counting Leaves (30分) (vector实现)

    题解: 用vector邻接表建图,两个邻接表实现层序遍历. 有注释在代码 代码: /*Keep on going Never give up*/ #pragma GCC optimize(3,&quo ...

  9. 1004 Counting Leaves (30 分)【难度: 中 / 知识点: 树的遍历】

    题目意思: 求每一层的叶子结点数 方法一: 深搜 数组模拟存储邻接表 #include<bits/stdc++.h> using namespace std; const int N=1e ...

最新文章

  1. Druid 大数据分析之快速应用(单机模式)
  2. Android客户端捕获http请求包的方法
  3. systemverilog硬件设计及建模_3D建模和渲染都吃什么硬件?设计师该如何选购电脑...
  4. 刚毕业的ERP实施顾问做甲方
  5. adf4350配置_配置MySQL以进行ADF开发
  6. 做旋转铁甲机器人_「铁甲评测」柳工CLG921E视频全面讲解
  7. 17 SD配置-企业结构-分配-分配允许的信用控制范围给公司码
  8. suse linux11 包括所有的linux操作系统的 遗忘root密码解决方案
  9. solidwork运行python脚本_Matlab – Solidworks 机器人建模(3)如何把URDF文件导入到Matlab...
  10. 阿里云ECS+Nginx+nginx_rtmp_module+FFMPEG服务器搭建过程
  11. 非常详细的机器学习知识点汇总(二)之SVM23问
  12. 关于计算机Excel中的试题,2015年职称计算机考试EXCEL练习试题及答案
  13. BAT文件中如何注释
  14. 【JAVA复习系列】第一部分
  15. at89s51单片机是几位微型计算机,单片机原理章习题
  16. 在前端如何玩转 Word 文档
  17. 安装LR11 时,安装Microsoft Visual c++2005 sp1运行时组件,就会提示命令行选项语法错误,键入“命令/?”可获取帮肋信息
  18. 20192209 Exp2-后门原理与实践
  19. 164work 综合练习1
  20. 互联网创业最好的时代

热门文章

  1. 多平台数据库客户端工具DBeaver
  2. 回复——在我测试的软件说明中,说安装好jboss后,在浏览器的地址栏中输入127.0.0.1:88这……...
  3. Alpha 冲刺 (9/10)
  4. Cacti+Nagios完全攻略(二)整合cacti与nagios安装部署
  5. 基类和派生类中使用static_cast和dynamic_cast进行类型转换
  6. memcached的基本命令(安装、卸载、启动、配置相关)
  7. 代码设置按钮样式的方法
  8. 随手小记 才知道系列
  9. 洛谷 P1985 翻转棋
  10. cocos2d-x 3.2 listview scorllview 等容器在小米华为等部分手机显示泛白解决