1049. Counting Ones (30)
题目如下:
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;
}
1049. Counting Ones (30)的更多相关文章
- PAT 解题报告 1049. Counting Ones (30)
1049. Counting Ones (30) The task is simple: given any positive integer N, you are supposed to count ...
- pat 甲级 1049. Counting Ones (30)
1049. Counting Ones (30) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The tas ...
- PAT 甲级 1049 Counting Ones (30 分)(找规律,较难,想到了一点但没有深入考虑嫌麻烦)***
1049 Counting Ones (30 分) The task is simple: given any positive integer N, you are supposed to co ...
- 【PAT甲级】1049 Counting Ones (30 分)(类似数位DP思想的模拟)
题意: 输入一个正整数N(N<=2^30),输出从1到N共有多少个数字包括1. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC #include& ...
- pat 1049. Counting Ones (30)
看别人的题解懂了一些些 参考<编程之美>P132 页<1 的数目> #include<iostream> #include<stdio.h> us ...
- PAT (Advanced Level) 1049. Counting Ones (30)
数位DP.dp[i][j]表示i位,最高位为j的情况下总共有多少1. #include<iostream> #include<cstring> #include<cmat ...
- PAT Advanced 1049 Counting Ones (30) [数学问题-简单数学问题]
题目 The task is simple: given any positive integer N, you are supposed to count the total number of 1 ...
- 1049 Counting Ones (30分)
The task is simple: given any positive integer N, you are supposed to count the total number of 1's ...
- PAT 1049 Counting Ones[dp][难]
1049 Counting Ones (30)(30 分) The task is simple: given any positive integer N, you are supposed to ...
随机推荐
- java实现生产者/消费者的三种方式
package com.wenki.thread; import java.util.LinkedList; import java.util.concurrent.LinkedBlockingQue ...
- Docker学习笔记【一】
[本篇学习笔记来源于 Docker 从入门到实践] 1.什么事Docker?[What] Docker在容器的基础上,进行了进一步的封装,从文件系统.网络互联到进程隔离等,极大的简化了容器的创建和维护 ...
- Linux学习之CentOS(十四)----磁盘管理之 硬连接与软件连接(转)
前言 在 Linux 底下的连结档有两种,一种是类似 Windows 的快捷方式功能的文件,可以让你快速的链接到目标文件(或目录),这种是软链接: 另一种则是透过文件系统的 inode 连结来产生新档 ...
- Linux学习之CentOS(十)----Linux 的账号与群组
Linux 的账号与群组 管理员的工作中,相当重要的一环就是『管理账号』啦!因为整个系统都是你在管理的, 并且所有一般用户的账号申请,都必须要透过你的协助才行!所以你就必须要了解一下如何管理好一个服务 ...
- Tomcat访问路径去掉发布项目的项目名称
需求: 把发布到Tomcat下的web项目,访问路径去掉项目名称 实现方式及原理: 方式一: 原理:Tomcat的默认根目录是ROOT,实际上ROOT这个项目在实际生产环境是没有用的,所以我们可以用我 ...
- java总结之基础类型与常量池
1.基础类型有byte short int long char boolean float double八种. 其中byte short int long char 的包装类型是存放在常量池(用来维护 ...
- 服务器&阵列卡&组raid 5
清除raid信息后,机器将会读不到系统, 后面若进一步操作处理, raid信息有可能会被初始化掉,那么硬盘数据就有可能会被清空, 导致数据丢失, 否则如果只是清除raid信息,重做raid是可以还原系 ...
- python学习之路网络编程篇(第四篇)
python学习之路网络编程篇(第四篇) 内容待补充
- Go 语言常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量. 常量中的数据类型只可以是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: const identifier [type] ...
- MYSQL 索引类型、什么情况下用不上索引、什么情况下不推荐使用索引
mysql explain的使用: http://blog.csdn.net/kaka1121/article/details/53394426 索引类型 在数据库表中,对字段建立索引可以大大提高查询 ...