题目大意
给出x,问你不小于x,且由相同个数的4和7组成的最小的数
解题思路
对于奇数位和大于当前位数最大数的直接特判掉
对于其他的dfs枚举,因为如果一个位置放得比原数大,那么后面的都确定了,所以是O(n)的
code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 100100
using namespace std;
int n,pp,a[N];
char s[N];
bool dfs(int x,int num1,int num2)
{if(x>n) return true;if(s[x]<'4'&&num1){//比原数大,那么后面直接贪心放最小的a[x]='4';num1--;for(int i=x+1;i<=n;++i)if(num1)a[i]='4',num1--;else a[i]='7',num2--;return true;}if(s[x]=='4'&&num1){a[x]='4';if(dfs(x+1,num1-1,num2))//尝试匹配return true;}if(s[x]<'7'&&num2){a[x]='7';num2--;for(int i=x+1;i<=n;++i)if(num1)a[i]='4',num1--;else a[i]='7',num2--;return true;}if(s[x]=='7'&&num2){a[x]='7';if(dfs(x+1,num1,num2-1))return true;}return false;
}
int main()
{while(~scanf("%s",s+1)){n=strlen(s+1);if(n&1){for(int i=1;i<=(n+1)/2;++i)putchar('4');for(int i=1;i<=(n+1)/2;++i)putchar('7');putchar(10);}else{pp=0;for(int i=1;i<=n/2;++i)if(s[i]>'7'){pp=1;break;}else if(s[i]<'7'){pp=2;break;}if(!pp){for(int i=n/2+1;i<=n;++i)if(s[i]>'4'){pp=1;break;}else if(s[i]<'4'){pp=2;break;}}if(!pp){for(int i=1;i<=n/2;++i)putchar('7');for(int i=1;i<=n/2;++i)putchar('4');putchar(10);}else if(pp==1){for(int i=1;i<=n/2+1;++i)putchar('4');for(int i=1;i<=n/2+1;++i)putchar('7');putchar(10);}else{if(dfs(1,n/2,n/2)){for(int i=1;i<=n;++i)putchar(a[i]);putchar(10);}}}}return 0;
}