4和7是两个幸运数字,我们定义,十进制表示中,每一位只有4和7两个数的正整数都是幸运数字。
前几个幸运数字为:4,7,44,47,74,77,444,447...
现在输入一个数字K,输出第K个幸运数。
第一行一个数字T(T<=1000)表示测试数据的组数。对于每组测试数据,输出一个数K
每组数据输出一行,第K个幸运数。
3
5
100
1000000000
74
744747
77477744774747744747444444447
首先把4和7化为0和1,分别对应起来看,题目就成了求第n位的二进制数,但是这个和普通的二进制数有点不一样。
各种进位的方法都能用的进制转换的方法来套用。
所以首先打个草稿找规律
/*0 - - 2的1次-2
//1 4 0
//2 7 1 2的2次-2
//3 44 00
//4 47 01 2的2次-2+2的一次
//5 74 10
//6 77 11 2的3次-2
//7 444 000
//8 447 001
//9 474 010
//10 477 011 2的3次-2+2的两次
//11 744 100
//12 747 101
//13 774 110
//14 777 111 2的4次-2
//15 4444 0000
*** **** ****
*/
可以看到很明显的几点:
1、当数字有1位时,出现了2次,
当数字有2位时,出现了4次,
当数字有n位时,出现了2^n次。
所以根据这个规律可以根据十进制n来求出二进制有几位。
for (int i=2;;i++)
if( n <= pow(2,i)-2 )
{length=i-1;break;}
这样就求出了二进制的length。
2、在长度为length的区间内,前面一半的数字都是以4打头,后面都是以7打头,
如果去掉头位并且在10位数中减去相应的次数,就可以变成一个length-1的十进制数。例:
输入十进制数13 求出length=3
13 2^3-2+2^2和 2^4-2之间 二进制为774
减去2^3 得到十进制为5 二进制为74
减去2^2 得到十进制为1 二进制位4
可以看到,当前最高位一步一步被取下来了。所以是一个很容易实现的循环。
方法想好以后,代码很快就来了:
#include<iostream> #include<string> using namespace std; int main() { int count = 0; cin >> count; int* array = new int[count]; for (int i = 0; i < count; ++i) { cin >> array[i]; } int n = 0; for (int i = 0; i < count; i++) { string ret; n = array[i]; int length; for (int j = 2;; j++) if (n <= pow(2, j) - 2) { length = j - 1; break; } while (length > 0) { length--; if (n > pow(2, length + 1) - 2 + pow(2, length)) { ret.append(1,'7'); n = n - (int)pow(2, length + 1); } else { ret.append(1,'4'); n = n - (int)pow(2, length); } } cout<<ret<<endl; } delete[] array; system("pause"); return 0; }
运行结果: