2021-09-29 洛谷模拟赛 T2 数字
思路:
因为要保证
4
4
4 的个数要和
7
7
7 的个数一样,所以输出串的长度一定是偶数
我们发现,对于任意一个输入长度
l
e
n
len
len 为奇数的字符串,答案一定是
4444
⋅
⋅
⋅
4477
⋅
⋅
⋅
7777
4444···4477···7777
4444⋅⋅⋅4477⋅⋅⋅7777(前半部分是
4
4
4, 后半部分是
7
7
7 注意
l
e
n
len
len 要
+
1
+1
+1)
那么偶数呢?
对于长度为偶数的字符串,我们使用深搜解决,每次判断当前位置填 4 还是填 7,如果填了的数比原来串当前位置的数字大,那么后面就是
4444
⋅
⋅
⋅
777
4444···777
4444⋅⋅⋅777 这样的了。
深搜时间复杂度为
O
(
哲
学
)
O(哲学)
O(哲学)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
#define ldb long double
using namespace std;
typedef long long ll;
const ll V=1e5+100;
char s[V],ans[V];
ll len;
bool flag;
inline ll in()
{
ll res=0,f=1;
char ch;
while((ch=getchar())<'0'||ch>'9')
if(ch=='-') f=-1;
res=res*10+ch-48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-48;
return res*f;
}
void put(ll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) put(x/10);
putchar(x%10+48);
}
void dfs(ll now,ll four,ll seven,string str,bool last_big)
{
if(flag) return ;
if(now>=len)
{
rep(i,0,len-1) ans[i]=str[i];
flag=true;
return ;
}
if(last_big) //上一个数已经比原串大了
{
rep(i,0,now-1) ans[i]=str[i];
rep(i,0,four-1) ans[i+now]='4';
rep(i,0,seven-1) ans[i+now+four]='7';
flag=true;
return ;
}
if(s[now]<='4'&&four) dfs(now+1,four-1,seven,str+"4",s[now]<'4'?1:0); //贪心填数
if(s[now]<='7'&&seven) dfs(now+1,four,seven-1,str+"7",s[now]<'7'?1:0);
}
int main()
{
// freopen("sj.txt","r",stdin);
while(scanf("%s",s)!=EOF)
{
// cout<<endl;
len=strlen(s);
if(len&1)
{
++len;
rep(i,1,len>>1) putchar('4');
rep(i,1,len>>1) putchar('7');
putchar(10);
}
else
{
flag=false;
memset(ans,0,sizeof(ans));
dfs(0,len>>1,len>>1,"",false);
if(!flag)
{
len+=2;
rep(i,0,(len>>1)-1) ans[i]='4';
rep(i,len>>1,len-1) ans[i]='7';
}
rep(i,0,len-1) putchar(ans[i]);
putchar(10);
}
}
return 0;
}