SRETAN

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;
    }
} 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值