ztr loves lucky numbers
Accepts: 99
Submissions: 736
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
ztr喜欢幸运数字,他对于幸运数字有两个要求 1:十进制表示法下只包含4、7 2:十进制表示法下4和7的数量相等 比如47,474477就是 而4,744,467则不是 现在ztr想知道最小的但不小于n的幸运数字是多少
输入描述
有T(1≤T≤105)组数据,每组数据一个正整数n,1≤n≤1018
输出描述
有T行,每行即答案
输入样例
2 4500 47
输出样例
4747 47
Hint
请尽可能地优化算法,考虑全面
1002.Solution
直接暴力显然TLE,考虑按位DFS
每一位只可能是4或7
所以根据这个来DFS即可,时间复杂度O(T∗2log10n)
考虑到T特别大,不可能每次都DFS
而经过计算,218=262144,所以全部储存下来
对于每次询问,二分即可
考虑一个边界条件,即当结果爆ll怎么办?
即答案应当为10个4、10个7的时候,显然unsigned long long也不行
那么只能采用特判了
AC代码:
#include<iostream> #include<functional> #include<algorithm> #include<cstring> #include<string> #include<vector> #include<cstdio> #include<queue> #include<cmath> #include<map> #include<set> using namespace std; #define CRL(a) memset(a,0,sizeof(a)) #define QWQ ios::sync_with_stdio(0) #define inf 0x3f3f3f3f typedef unsigned long long LL; typedef long long ll; const int T = 1000000+50; const int mod = 1000000007; set<LL> se; set<LL>::iterator it; struct node { int c1,c2; LL v; node(){} node(int _1,int _3,LL _2):c1(_1),c2(_3),v(_2){} }; void Play_table() { queue<node> q; q.push(node(1,0,4));q.push(node(0,1,7)); while(!q.empty()) { node cur = q.front();q.pop(); if(cur.c1>8||cur.c2>8)continue; if(cur.c1+cur.c2<16){ q.push(node(cur.c1+1,cur.c2,cur.v*10+4)); if(cur.c1+1==cur.c2)se.insert(cur.v*10+4); } if(cur.c1+cur.c2<16){ q.push(node(cur.c1,cur.c2+1,cur.v*10+7)); if(cur.c1==cur.c2+1)se.insert(cur.v*10+7); } } } int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif Play_table(); ll n,m,i,j,k; scanf("%I64d",&n); while(n--) { scanf("%I64d",&m); if(m>7777777744444444){ printf("44444444447777777777\n"); continue; } it = se.lower_bound(m); printf("%I64d\n",*it); } return 0; }