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 ...
随机推荐
- 从零开始搭建口袋妖怪管理系统(2)-借助ngRoute实现详情页面跳转
一.目标 上一次我们用Angular1.x完成了简单的口袋妖怪展示列表页面,现在我们想要了解口袋妖怪更多的信息,但是发现原有单行表格可能容纳不下口袋妖怪的所有信息,所以现在我们需要一个口袋妖怪详情界面 ...
- 携程Java后台开发三面面经
前言 携程是我面试的第一个互联网公司,投递的岗位是后台开发实习生,总共面了三面,止步于人才库.中间兜兜转转,复杂的心理活动,不足与外人道也.唯有面试的技术部分与大家共享. 宣讲会完了之后有个手写代码的 ...
- [Luogu 1516] 青蛙的约会
Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事 ...
- java1.8十大新特性详解
"Java is still not dead-and people are starting to figure that out." 本教程将用带注释的简单代码来描述新特性,你 ...
- 补充Mysql5.7用法
下面简单介绍一下安装: [root@MySQL soft]# tar xf mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz -C /data/service/ [r ...
- Linux 管理软件
公司的openfire先前运行在windows上的,但由于在windows上openfire内存机制问题,最多只能占用2GB内存,且时间稍微长久一些就会自动挂掉,用户无法登陆和连接,因此迁移到了Cen ...
- LintCode题解之统计数字
直接硬搜就可以了,只是需要考虑k为0的情况. public class Solution { /* * @param : An integer * @param : An integer * @ret ...
- docker环境 快速使用elasticsearch-head插件
docker环境 快速使用elasticsearch-head插件 #elasticsearch配置 #进入elk容器 docker exec -it elk /bin/bash #head插件访问配 ...
- android 调试工具ADB命令详解
adb是什么? adb的全称为Android Debug Bridge,就是起到调试桥的作用. 通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具. ...
- 等价于n*n的矩阵,填写0,1,要求每行每列的都有偶数个1 (没有1也是偶数个),问有多少种方法。
#define N 4 /* * 公式: * f(n) = 2^((n - 1) ^2) */ int calWays(int n) { int mutiNum = (n - 1) * (n - 1) ...