• 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’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

    题目分析

    已知一个正整数N,求1~N的正整数中出现1的次数(如:11算出现两次1)

    解题思路

    从低位到高位,计算每一位为1时的数字个数,进行累加

    • 如果当前位为0, 左边为0left-1时都可以在当前位取1(此时右边可以取到的数字总数为099999...即:a个),因为当前位为0,所以左边取left时不能取1。
    • 如果当前位为1,左边为0left-1时都可以在当前位取1(此时右边可以取到的数字总数为099999...即:a个),当前位为1时,右边只可以取到0~right(即:right个数)
    • 如果当前位大于2,左边为0left时都可以在当前位取1(此时右边可以取到的数字总数为099999...即:a个)

    易错点

    1. 若枚举1~N数字,再对数字统计出现1的次数,会超时(测试点4,6)

    知识点

    1. 已知正整数为N,从右往左,指针i指向N的某个位置,a当前位的权重(如:i=2,a=102;i=0,a=100)
    N/(a*10) //取指针i指向的数字左边数字
    N/a%10 //取指针i指向的数字
    N%a //取指针i指向的数字右边数字
    

    Code

    Code 01

    #include <iostream>
    using namespace std;
    /*
    测试点4,6超时
    */
    int main(int argc,char * argv[]) {
    	int n,t=0,a=1,left,now,right;
    	scanf("%d",&n);
    	while(n/a>0) {
    		left = n/(a*10),now=n/a%10,right=n%a;
    		if(now==0)t+=left*a;
    		else if(now==1)t+=left*a+right+1;
    		else t+=(left+1)*a; 
    		a*=10;
    	}
    	printf("%d",t);
    	return 0;
    }
    
  • 相关阅读:
    Manage Files on HDFS via Cli/Ambari Files View——如何在ambari上查看HDFS文件
    Windows Authentication
    request.getParameterMap 无法获取到参数的原因
    sql server 分割字符串存储过程
    URI.js – 全能的URL操作库
    低延迟视频流播放方案探索
    mysql 替换函数replace()实现mysql替换指定字段中的字符串
    如何在npm上发布自己的包
    sharp 安装过慢
    Error: EACCES: permission denied, mkdir
  • 原文地址:https://www.cnblogs.com/houzm/p/12258899.html
Copyright © 2020-2023  润新知