SRETAN

来源:互联网 发布:工作量统计软件 编辑:程序博客网 时间:2024/04/28 11:36

SRETAN

(sretan.pas/c/cpp)
题目描述
4和7是幸运数字,输入k,输出第k个只含有4和7的数。
输入格式
一行一个数k
输出格式
一行一个数表示答案
样例输入
3
样例输出
44
数据范围与约定
1 <= k <= 10^9

思路

这个题是一个可以说是数论相关的题目,因为输出的数字串中只有4与7两种,所以我们考虑二进制。显然,我们要把4当做01中的较小数字,也就是0;7就相当于1。然后发现规律:
4 7(2个)
44 47 74 77(4个)
444 447 474 477 744 747 774 777(8个)
所以我们发现可以用如下公式表示:
k=2+4+8+16+…+2^m+c
举个例子吧,15=2+2^2+2^3+1,1就是c(某个常数),3就是m(最大幂数)。
接下来就是解释一下c与m的意义,m+1就能表示第k个数的位数,c-1表示共(m+1)位的数字用二进制所表示的数(原因是因为全是0也符合题意),如果不明白,我们继续拿15当做例子:
已知15=2+2^2+2^3+1,
那么输出的数字就是XXXX这四位数,因为1-1在二进制中是0,所以为XXX0,前面不足为的用较小的数字补全,就是0000,转化为4或7组成的数就是4444。
换一个大一点的例子:
k=1000
k=1000=2+2^2+2^3+2^4+2^5+2^6+2^7+2^8+490
这样,m=8,c=490,m+1=9,c-1=489。
同样,空出9(m+1)位,XXXXXXXXX
489用二进制表示111101010
正好填满,然后转化成47数列,777747474。

代码

#include<iostream>  #include<cmath>using namespace std;int i,j,m,t;long long temp,n;int b[1001];int f(long long x){    temp=2;    t=0;    while(1)    {        m=x;        x-=temp;        t++;        if(x<=0)        break;        temp*=2;    }    return m-1;}void jz(int x){    i=1;    while(x)    {        b[i]=x%2;        x/=2;        i++;    }} int main()  {    freopen("sretan.in","r",stdin);    freopen("sretan.out","w",stdout);    cin>>n;    jz(f(n));    for(i=t;i>=1;i--)    {        if(b[i])        cout<<7;        else        cout<<4;    }} 
3 0
原创粉丝点击