问题描述:
4和7是两个幸运数字,我们定义,十进制表示中,每一位只有4和7两个数的正整数都是幸运数字。前几个幸运数字为:4,7,44,47,74,77,444,447……现在输入一个数字K,输出第K个幸运数。
输入:
第一行一个数字T(T<=1000)表示测试数据的组数。对于每组测试数据,输出一个数K(1<=K<=10^18)
输出:
每组数据输出一行 ,第K个幸运数。样例输入:
3
5
100
1000000000
样例输出:
74
744747
77477744774747744747444444447
解题思路:
首先是需要知道这个幸运数字的构造的规律,只有1位的时候,是4,7;有2位的时候,是44,47,74,77;有3位的时候,是444,447,474,477,744,747,774,777;看了这里,我们就能够看到这个数字的构造规律了,我们把4当做二进制中的0,7当做二进制中1,则1位的时候就是0,1;2位的时候就是00,01,10,11;3位的时候就是,000,001,010,011,100,101,110,111,依次类推……
当1位的时候,有两个幸运数;2位的时候有2^2个幸运数,3位的时候有2^3个幸运数,……n位的时候含有2^n个幸运数字;我们知道第1,2大的幸运数字是1位,第3,4,5,6的幸运数字是2位,第7,8,9,10,11,12,13,14大的幸运数字是3位,所以知道第K大的数字是(long long)log2(K+1)位;
我们知道第K大的数字是(long long)log2(K+1)位,那么(long long)log2(K+1)-1位可以表示的数字一共有(等比数列的前n项和)(long long)pow(2,(long long)log2(K+1))-2;所以(long long)log2(K+1)位只需要表示的数字就是N=K-(long long)pow(2,(long long)log2(K+1))-2-1(最后要减1);在把N转换成二进制,如果这bit数字是0对应于4,bit是1对应于7;
例:第100大的数字,先求(long long)log2(100+1)等于6,那么前面有1位,2位,3位,4位,5位的,一共有2+2^2+2^3+2^4+2^5=2^6-2=62个,则6位的应该是100-62-1=37,再把37换成6位的二进制,是100101,所以第100大的数字就是744747
代码:
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
long long bitNumber(long long n)
{
return (long long)log2(n + 1);
}
long long preNumber(long long bitnumber)
{
return (long long)pow(2, bitnumber + 1) - 2;
}
void result(long long Num)
{
long long bitN = bitNumber(Num);
long long preN = (bitN - 1);
long long temN = Num - preNumber(preN)-1;
vector<int> res;
for (int i = 0; i < bitN; i++) {
res.push_back(4);
}
int k = res.size() - 1;
while (temN) {
long long t = temN&1;
if (t) {
res[k] = 7;
}
temN >> = 1;
k--;
}
for (int i = 0; i < res.size(); i++) {
cout << res[i];
}
cout << endl;
}
int main()
{
long long ni;
int num;
cin >> num;
for (int i = 0; i < num; i++) {
cin >> ni;
result(ni);
}
return 0;
}