Problem
Description
给定一个正整数 n,请你找到一个正整数 x,要求:
-
x ≥ n
-
x 的各个数位均不包含 77 和 99 以外的数字,且 x 中包含的 77 的数量与 99 的数量恰好相等。
满足前两个条件的前提下,x 应尽可能小。
Format
Input
一个正整数 n。
Output
一个正整数,表示 x。
Samples
Sample Input 1
4500
Sample Output 1
7799
Sample Input 2
1
Sample Output 2
79
Limitation
1s, 1024KiB for each test case.
前 66 个测试点满足 1 ≤ n ≤ 5000。
所有测试点满足 1 ≤ n ≤ 。
Solution
算法与解法
此题找不到任何规律,所以我们需要挨个遍历每一位,最后组成一个 m,在符合题意的情况下,求出 m 的最小值,就是 x 了。根据需求,深搜最满足要求。
时间复杂度
这一题需要用到深搜,由于每个位要么是 7,要么是 9,所以普通情况下时间复杂度为 ,其中 k 为 n 的位数。但在极端情况下,例如 857,最终 x 为 7799,x 的位数比 n 多一个,所以 我们需要多遍历一个位数,由于我们不知道 x 是否与 n 位数相同,我们需要假设答案与 n 位数相同进行遍历,如果找不到 x,就再次进行遍历,所以最后的时间复杂度为 。
n 最大值为 ,k 最大值为 9,所以时间复杂度最大为 ,不可能超时。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAX = 1e11 + 1;
int res = MAX, sum, n;
void dfs(int num, int now, int n7, int n9){ //num 为组成的数,now 为 num 的位数,n7 为 num 中 7 的个数,n9 为 num 中 9 的个数
if(now == sum){
if(n7 == n9 && num >= n) //判断是否符合题意
res = min(res, num); //比较最小值
return ;
}
int knum = num * 10 + 7;
dfs(knum, now + 1, n7 + 1, n9);
if(res == MAX) //如果前面已经找到 x,不必继续深搜,因为后面搜的数一定比 x 大
dfs(knum + 2, now + 1, n7, n9 + 1);
}
signed main(){
scanf("%lld", &n);
int k = n;
while(k){ //判断位数
sum ++;
k /= 10;
}
dfs(0, 0, 0, 0); //深搜
if(res == MAX){ //代表最终的 x 比 n 多一位,重新深搜
sum ++;
dfs(0, 0, 0, 0);
}
printf("%lld", res);
return 0;
}