这道题是 BestCoder Round #82 (div.2) 的第二道题,题意很简单,首先定义一个幸运数的概念。幸运数就是至少包含一个4或者7,并且4的个数和7的个数必须相等,例如4、7,4477.....给你一个数,要你找到最小的幸运数,但不能小于所给定的这个数。做比赛的时候,我的同学一上来就模拟结果可想而知,我也想了下模拟,发现很容易漏掉一些情况,想到了暴力,给定的数小于10e18,暴力的话就是找到所有的幸运数,共有2e18次方算了下不大,但是有10e5组数据,但是就觉得不行,也就没继续想下去,赛后看了题解暴力+二分,我的天,二分.......顿时感觉自己懵逼了,我怎么没想到呢?还是实力弱啊。赛后用暴力+二分写了一发,WA....这什么情况,仔细再想下,有一种特殊的情况要特判,就是输入10e18次方的时候输出的结果是44444444447777777777,已经超出了长整型的范围,所以当二分的结果大于最后一个数的时候,结果为44444444447777777777就ok了。二分这种思想还真的是很重要的啊!
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 300005;
LL save[N];
int cnt = 0;
void dfs(LL value, int num4, int num7)
{
if(value>=1e18)
return ;
if(num4 == num7 && num4>0)
save[cnt++] = value;
dfs(value*10+4, num4+1, num7);
dfs(value*10+7, num4, num7+1);
}
int binary_reserach(LL value)
{
int l = 0, r = cnt-1, mid;
while(l<=r)
{
int mid = (l+r)/2;
if(save[mid] < value)
l = mid+1;
else
r = mid-1;
}
return l;
}
int main()
{
dfs(0, 0, 0);
sort(save, save+cnt);
//cout<<save[cnt-1]<<endl;
int T;
scanf("%d", &T);
while(T--)
{
LL data;
scanf("%I64d", &data);
int index = binary_reserach(data);
if(index == cnt)
cout<<"44444444447777777777"<<endl;
else
cout<<save[index]<<endl;
}
return 0;
}