问题 C: 幸运数字II
时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]
题目描述
数字4和7是幸运数字,而其他的都不是幸运数字。一个整数是幸运数字,当且仅当它的十进制表示只包含幸运数字。
现在让你给出第K大的幸运数字。
输入
第一行一个整数K(1<=K<=1,000,000,000)
输出
第K大的幸运数字。
样例输入
Copy
1
样例输出 Copy
4
首先把4和7化为0和1,分别对应起来看,题目就成了求第n位的二进制数。但是这个和普通的二进制数有点不一样,
各种进位的方法都不能用的进制转换的方法来套用。
所以首先打个草稿找规律 ( 真TM郁闷,每次比赛时无论怎么都找不到规律... )
/*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 二进制1
//9 474 010 二进制2
//10 477 011 二进制3 2的3次-2+2的两次
//11 744 100 二进制4
//12 747 101 二进制5
//13 774 110 二进制6
//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<cstdio> #include<iostream> #include<algorithm> #include<map> #include <math.h> #include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } const int INF=0x3f3f3f3f; const int maxn=5e5; ll n; int p; void inint(){ cin>>n; } int main(){ inint(); for(int i=2;i<=1e9;i++){ ll o=pow(2,i)-2; if(n<=o){ p=i-1; break; } } cout<<p<<endl; while(p--){ int q=pow(2,p+1)-2+pow(2,p); if(n>q){ printf("7"); n-=pow(2,p+1); } else{ printf("4"); n-=pow(2,p); } } }
ac代码2;
#include<cstdio> #include<iostream> #include<algorithm> #include<map> #include <math.h> #include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } const int INF=0x3f3f3f3f; const int maxn=5e5; ll n; int z; char b[maxn]; map<int,int>mp; void inint(){ cin>>n; } int main(){ inint(); int l; for(int i=2;i<=1e9;i++){ ll o=pow(2,i)-2; if(n<=o){ z=i-1; l=n-(pow(2,i-1)-2)-1; break; } } if(l==0){ for(int i=1;i<=z;i++){ printf("4"); } } else{ int p=l; int zz=1; while(p){ b[zz++]=p%2; p/=2; } int o=1; for(int i=z;i>=1;i--){ if(b[i]==1){ mp[o]=1; } o++; } for(int i=1;i<=z;i++){ if(mp[i]==1){ printf("7"); } else{ printf("4"); } } } }
原文地址:https://www.cnblogs.com/lipu123/p/12694695.html