zoukankan      html  css  js  c++  java
  • [编程题]页码统计

    题目

    牛客网 https://www.nowcoder.com/questionTerminal/3a003cb6a3174ef9835fa603e01d8b52

    牛客网原题:
    牛牛新买了一本算法书,算法书一共有n页,页码从1到n。牛牛于是想了一个算法题目:在这本算法书页码中0~9每个数字分别出现了多少次?

    思路

    按位数某个数字出现过多少次。也就是说,固定某一位上的某个数,看看此时有几种情况。

    举个栗子:
    对统计1~785012中5出现的个数
    我们先考虑5在低位第三位出现的次数,我们就将第三位固定为5:XXX5XX。
    此时,问题就转化为,“X”处一共有多少种组合方式。
    高位的3位可以从000到785之间,低位的2位可以从00到99之间。
    但是,当高3位为785时,7855XX无论如何都超过了785012,因此,高三位可以选择的只有000~784(共785个数字),高三位和低二位一共有785*100种组合方式。

    我们再考虑5在低位第四位出现的次数,我们就将第四位固定为5:XX5XXX。
    与前面相同,高位的二位可以从00到78之间,低位的三位可以从000到999之间。
    当高位是00到77时,与前面一种情况是相同的,一共可以组合出78*1000种情况。
    当高位是78时,785XXX就有超过785012的可能了,后三位的选择局限在000到012之间,共13中情况。
    两者结合就是:78*1000+13

    最后考虑5在低位第5位出现的次数,我们就将第五位固定为5:X5XXXX。
    与前面相同,最高位可以从0取到7,低四位可以从0000取到9999.
    当最高位为0到6时,与第一种情况相同,一共可以组合出7*10000中情况。
    当高位是7时,与前面的情况不同的是,75XXXX是不会越界的,后四位可以从0000取到9999,所以可以组合出10000中情况。
    两者结合就是:7*10000+10000

    但是,当统计0的个数时,情况又有所不同。还用785012讨论,如果我们要统计低位低2位出现0的次数,按照前面的方法,我们可能把00000X讨论进来,认为这也是第二位出现0的情况,但是这个数只能表示为X,它的第二位根本不存在。
    因此,针对0这种情况,我们需要单独讨论,只需要分成两类,不可能存在当前位小于0的情况,不过每次高位的取值要把全0的情况剔除。

    代码

    我的代码如下

    #include <iostream>
    using namespace std;
    
    //count the bit of N, and the low_n/high_n at lowest bit/highest bit
    int countBit(int n, int *low_n, int *high_n)
    {
    	int t = n;
    	int res = 0;
    	int high;
    	*low_n = t % 10;
    	while (t > 0)
    	{
    		res++;
    		high = t % 10;
    		t = t / 10;
    	}
    	*high_n = high;
    	return res;
    }
    
    int pow(int n, int x)
    {
    	int t = 1;
    	for (int i = 0; i < x; i++)
    		t *= n;
    	return t;
    }
    
    int main(int argc, char** argv)
    {
    	int n;
    	int i, j, k, t;
    	int low, high, len;	//low: 0th number; high: len-th number; len: lenghth of n;
    	int lown, highn, curn;	//highn: number before current bit, lown: after curent bit; curn: current bit;
    	int result[10];
    	
    	cin >> n;
    	len = countBit(n, &low, &high);
    
    	for (i = 0; i < 10; i++)	result[i] = 0; 
    	for (i = 0; i < len; i++)
    	{
    		t = pow(10, i);
    		highn = n / (t * 10);	lown = n%t;	curn = (n/t) % 10;
    		for (j = 0; j < 10; j++)
    		{
    			if (j == 0)
    			{
    				if (i == len - 1)
    					continue;
    				if (curn == 0)
    					result[j] += (highn - 1)*t + (lown + 1);
    				else
    					result[j] += highn * t;
    			}
    			else if (j == curn)
    				result[j] += highn * t + (lown + 1);				
    			else if (j>curn)
    				result[j] += highn * t;
    			else //j<curn && j!=0
    				result[j] += (highn+1) * t;
    		}
    	}
    	//output
    	cout << result[0];
    	for (i = 1; i < 10; i++)
    		cout << " " << result[i];
    	return 0;
    }
    

     PS,自己写pow函数的原因 - 公司的算法考试不允许使用stdlib和stl,所以习惯自己写。

    这是我的第一个newcoder题。

  • 相关阅读:
    flask综合整理1
    flask
    linux
    用户登录权限汇总
    DRF之注册响应分页组件
    MVC 过滤器 构建会员是否登录
    压缩文本、字节或者文件的压缩辅助类-GZipHelper
    MVC 构建图片/文件选择器 参考其它CMS功能
    MVC5+EF6 简易版CMS(非接口) 第四章:使用业务层方法,以及关联表解决方案
    MVC5+EF6 简易版CMS(非接口) 第三章:数据存储和业务处理
  • 原文地址:https://www.cnblogs.com/bouygues/p/7372942.html
Copyright © 2011-2022 走看看