数字之谜

问题1:从1,2,3,····,n,共有多少个1数字?

例子从1-12,共有5个1数字,结果如下

思路

我们知道最大值N,

暴力法:就是计算1-n的每个数里还有1数字的个数,然后相加即可,时间复杂度O(N*(每个数字的位数长度))

对于每个数,计算它还有1数字的个数的思路

先取来每位数字,对于一个数m,它的位数长度我们用length(int m)方法来求得

1)计算整数位数思路如下

// function 23: 计算一个整数有多少位数
// 输入: 一个整数
// 输出:整数的位数
int IntData_number(int N)
{
	int data = N;
	int length  = 0;
	while(data != 0)
	{
		data = data/10;
		length ++;
	}
	return length ;
}

2)抽取整数第i位操作思路如下

	n = pow(10.0,i);
	bit = ( N % n ) / (n/10) ;

3)然后对每一位判断是不是1即可

优化法:首先我们能得到最大数N的位数为length(用到的方法如上)

然后我们转换问题:数字的组合排列问题

思路如下

int f(int N)
{
	int result = 0;
	int length = 0;
	int bit = 0;
	int n = 0;
	int now = 0;

	if( N>0 )
	{
		// 对于长度为1 的数字处理
		if(N<=9)
			return 1;

		length = String::IntData_number(N);
		//对于长度>1的数字处理
			// 对个位处理
				// 如果个位是 0,则高位有( n/10 +1(算上0) - 1(因为个位是0,最大的数不能要))个选择
				if( N%10  ==  0 )
					result = N/10 ;
				// 否则 则高位有 ( n/10 +1(算上0))个选择
				else result = N/10 +1;

			// 对2 -(n-1)位处理
			for(int i = 2;i<length;i++)
			{
				//获取第i位数字
					n = pow(10.0,i);
					bit = ( N % n ) / (n/10) ;
				//第i位为 0,则高位的选择为 N/ (10^i) +1-1(因为包括0,不包括最高位)
				//低位选择为 10^(i-1)
				if(bit == 0)
				{
					now = (N/n )*(n/10) ;
				}
				//第i位为1,则高位的选择为 N/ (10^i) +1-1(因为包括0,不包括最高位)
				//低位选择为 10^(i-1)
				//同时还得加上高位为最大时,低位上的选择N%(10^(i-1))+1(因为包括 0)
				else if(bit == 1)
				{
					now = (N/n )*(n/10) ;
					now += N % (n/10) +1;
				}
				//第i位>1,则高位的选择为 N/ (10^i) +1(因为包括0,包括最高位)
				//低位选择为 10^(i-1)
				else
				{
					now = (N/n+1)*(n/10) ;
				}
				result += now ;
			}

			// 对最后一位处理
			if(length > 1)
			{
				bit = N /(int)(pow(10.0,length-1));
				// 对于最后一位是 1,则其后面的数+1(因为包括0)
				if( bit==1 )
				{
					result += N % (int)(pow(10.0,length-1)) + 1;
				}
				// 否则 为 10^(n-1),每一个都有10个取值选择
				else if(bit > 1)
				{
					result += (int)(pow(10.0,length-1));
				}
			}
	}
	//else cout<<"N<=0"<<endl;
	return result;
}

优化法运行结果

部分截图如下

程序注释 每一行第一个数为N,第二个数为问题答案

问题2:

对于问题1,求出f(N),现在问题求出f(N)= N时N的最大值

对于数学来说,N值会很大,有可能超出int最大值,也可能不超出,这个我也没法证明

我的思路是从int最大值逐渐减小然后求得符合条件的N值

思路:

		int i = numeric_limits<int>::max(),m;
		while(true)
		{
			m = f(i);
			if(i == m)
			{
				cout<<i<<"     "<<m<<endl;
				break;
			}
			i--;
		}

结果:

程序运行结果如下

即求出的最大值为途中所示。

数字之谜

时间: 2024-11-02 23:38:11

数字之谜的相关文章

数字用加法分解之谜

数字用加法分解之谜 个人信息:就读于燕大本科软件工程专业 目前大三; 本人博客:google搜索"cqs_2012"即可; 个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献; 编程语言:C++ ; 编程坏境:Windows 7 专业版 x64; 编程工具:vs2008; 制图工具:office 2010 powerpoint; 硬件信息:7G-3 笔记本; 真言 蜗牛虽慢,却不曾后退. 题目 数字用加法分解之谜: 1+2 = 3 4+5 = 9 2+3+4 = 9

Java解惑六:库之谜

本文是根据JAVA解惑这本书,做的笔记. 电子书见:http://download.csdn.net/detail/u010378705/7527721 谜题56 BigInteger.BigDecimal以及包装类型的实例是不可改变. BigInteger five = new BigInteger("5"); BigInteger total = BigInteger.ZERO; total.add(five); //这并不会改变total的值,调用该方法的返回值,才是加法得到的结

grep前传之侠影之谜 (Grep begins)

一.自述 我叫grep,是同你们一样,生活在都市里.每天做着重复的事,忙碌着. 说起来这个好笑,我生活的国家叫Bourne-Again Shell,因为我国来往人多,大家读者不便,于是心口不一的叫它"bash".bash,呵呵,好像被狠狠的砸了一下. 眼前这座烂尾楼便是我藏身的地方,它叫/bin,这里的居民都是上班族,那天下班后我数了一下用户,发现114个住户!天哪,好一座危楼! 在这个国家每家每户都供奉着一尊雕像,它叫root,对了,我和我的家人(group)都属于它,无理由的信奉着

【转】String hashCode 方法为什么选择数字31作为乘子

某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主角31.这个数字居然不是用常量声明的,所以没法从字面意思上推断这个数字的用途.后来带着疑问和好奇心,到网上去找资料查询一下.在看完资料后,默默的感叹了一句,原来是这样啊.那么到底是哪样呢?在接下来章节里,请大家带着好奇心和我揭开数字31的用途之谜. 2. 选择数字31的原因 在详细说明 String hashC

String hashCode 方法为什么选择数字31作为乘子

1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主角31.这个数字居然不是用常量声明的,所以没法从字面意思上推断这个数字的用途.后来带着疑问和好奇心,到网上去找资料查询一下.在看完资料后,默默的感叹了一句,原来是这样啊.那么到底是哪样呢?在接下来章节里,请大家带着好奇心和我揭开数字31的用途之谜. 2. 选择数字31的原因 在详细说明 String

基于C#的机器学习--贝叶斯定理-执行数据分析解决肇事逃逸之谜

贝叶斯定理-执行数据分析解决肇事逃逸之谜 ? 在这一章中,我们将: 应用著名的贝叶斯定理来解决计算机科学中的一个非常著名的问题. 向您展示如何使用贝叶斯定理和朴素贝叶斯来绘制数据,从真值表中发现异常值等等 贝叶斯定理概况 当我们使用贝叶斯定理的时候,我们是在测量一件事发生的概论程度: ? 上式表示在给定事件B的情况下事件A发生的概率. 概率通常被量化为0和1之间的一个数,包括这两者;0表示不可能,1表示绝对肯定.概率越大,确定性越大.掷骰子得到6的概率和掷硬币得到正面的概率这两个例子你们肯定很熟

【谜客帝国】第17届阳光原创联想题会(2015.3.16)

[谜客帝国]第17届阳光原创联想题会(2015.3.16)主持:瓷   计分:晴画1.此题   开始   歌曲   甲子  1   一2.双杠   愚蠢   其中   丑牛  1   二3.网开一面  玲珑曲线   一再包抄  真心团圆   3  三围4.太祖革弊强国运  政务公开除陈规日中差距从此始  发展才是硬道理   4  明治维新5.经典童话  埃及少女  刚刚上映  郑钧歌曲   3 灰姑娘6.新年快乐  狼不出没  未必高兴  南朝人名   2  羊欣7.新年雨连绵  猴头探龙宫 未

JDK1.8源码学习-String-hashCode方法为什么选择数字31作为乘子

1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主角31.这个数字居然不是用常量声明的,所以没法从字面意思上推断这个数字的用途.后来带着疑问和好奇心,到网上去找资料查询一下.在看完资料后,默默的感叹了一句,原来是这样啊.那么到底是哪样呢?在接下来章节里,请大家带着好奇心和我揭开数字31的用途之谜. 2. 选择数字31的原因 在详细说明 String

大写中文数字-財务

壹.贰.叁.肆.伍.陆.柒.捌.玖.拾.佰.仟.万.亿.元(圆).角.分.零.整.这是大家常常要填写的大写数字,问什么要用大写数字呢?想必非常多人都不是非常清楚! 先看看下面两个有关大写数字的表格: 1.数码与大.小写数字的对比表: 数码 小写数字 大写数字 0 ○ 零 1 一 壹 2 二 贰 3 三 叁/參 4 四 肆 5 五 伍 6 六 陆 7 七 柒 8 八 捌 9 九 玖 2.进位数码与大.小写数字的对比表 数码 小写数字 大写数字 10 十 拾 20 二十 廿 30 三十 卅 100