京东2017届毕业生校园招聘笔试题《第K个幸运数字》

考题回忆如下:
所谓幸运数字就是每一位的数字除了4就是7,例如4,7,44,47,74,77,444,447,474,477,744,747,774,777....。第K个幸运数字就是,就是所有幸运数字从小到大排列,第1个为4,第2个为7,第3个为44,第4个为47,第5个为74.......
输入第一行为求幸运数字的个数T(1≤T≤1000),之后每行是要求的第K个幸运数字(1≤K≤1018
例如:
本地输入:
3
5
100
1000000000
输出:
74
744747
77477744774747744747444444447
本人的代码如下(仅代表个人观点,并不代表最优):
#include<iostream>
#include<math.h>
#include<list>
using namespace std;
void PrintNum(list<int> Lis,int cnt)
{
	while (Lis.size()<cnt--)
	{
		cout<<4;
	}	
	 for(list<int>::iterator itr=Lis.begin();itr!=Lis.end();++itr)
	{
		if(*itr==0)
			cout<<4;
		else
			cout<<7;
	}
	cout<<endl;
}
list<int> BinaryVector(long long n)
{
	long long temp;
	temp = n;
	list <int> L;
	while(0 != temp)
	{
		L.push_front(temp % 2);
		temp = temp >> 1;
	}
	return L;
}
int main()
{
	int T;
	cin>>T;
	long long *K=new long long[T];
	for(int i=0;i<T;++i)
	{
		cin>>K[i];
	}
	for(int i=0;i<T;++i)
	{
		long long temp=0;
		int j=0;
		while (temp<=K[i])
		{
			++j;
			temp=pow(2,j);
		}
		if(pow(2,j)==K[i]+1)
		{
			temp=K[i]+2-pow(2,j);
			list<int> Lis=BinaryVector(temp-1);
			PrintNum(Lis,j);
		}else
		{
			temp=K[i]+2-pow(2,j-1);
			list<int> Lis=BinaryVector(temp-1);
			PrintNum(Lis,j-1);
		}
	}
	delete K;
	system("PAUSE");
	return 0;
}
解题思路:
先观察幸运数字:4,7,44,47,74,77,444,447,474,477,744,747,774,777....
不难得出如下两个结论:1.n位幸运数字的个数是2n个。假设第K个幸运数字是由n位数字组成,则可将K分成两部分,前n-1位数字总数 2 1 + 2 2 + 2 3 +...+. 2 n-2 + 2 n-1  与 K-( 2 1 + 2 2 + 2 3 +....+ 2 n-2 + 2 n-1 )的和,所以第K个幸运数字就是n位数字中的第K-( 2 1 + 2 2 + 2 3 +....+ 2 n-2 + 2 n-1   )个,这样分的好处可以从结论2发现;
                          2.每位数字除了4就是7,相当于只有4和7的二进制,可以把它转换成0/1表示的二进制,所以幸运数字 4,7,44,47,74,77,444,447,474,477,744,747,774,777....就是0,1,00,01,10,11,000,001,010,011,100,101,110,111.....结合结论1这个题进一步的转换成n位二进制第 K-( 2 1 + 2 2 + 2 3 +....+ 2 n-2 + 2 n-1 )个二进制数是多少?可以首先判断有多少位,然后再判断第几个。
例如:第5个幸运数字是由两位数字组成,5是由两位幸运数字组成的第5 - 2 1 =3个,即00,01,10,11的第3个10,转换由7和4组成幸运数字就是74。
注意事项: 1.K的范围是1~1018,所以不要用累加的方法求幂运算,否则会超时,解决方法有两个,一个事用数***算库math.h中的幂运算函数double pow(int,int),或者用位运算右移。
                    2.高位为0的时候,没有补零会造成输出结果错误,如两位数、三位数的第3个幸运数字不补零都是74,而三位数应该是474
                    3.2 1 + 2 2 + 2 3 +....+ 2 n-2 + 2 n-1=2n-2
#京东#
全部评论
循环有点多啊,我也发了java的代码,可以看看 http://www.nowcoder.com/discuss/8602?type=0&order=0&pos=63&page=1
点赞 回复 分享
发布于 2016-09-06 11:21
就7行左右的代码吧,怎么那么长哦
点赞 回复 分享
发布于 2016-09-06 12:35
4...7...,非要说成幸运数.怪不得一直赔钱...
点赞 回复 分享
发布于 2016-09-06 12:05
只要储存就不行就会超时。。
点赞 回复 分享
发布于 2016-09-06 11:21

相关推荐

ResourceUtilization:四六级不愧是大学最有用的证之一
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务