Educational Codeforces Round 39 (Rated for Div. 2) 946E E. Largest Beautiful Number
题:
OvO http://codeforces.com/contest/946/problem/E
CF 946E
解:
记读入串为 s ,答案串为 ans,记读入串长度为 len,下标从 1 开始。
分三种情况讨论
1.数字位数为奇数,设数字位数为 len,则输出 ( len-1 ) 个 9 即可
2.数字位数为偶数,其中最高位为1,最低位为 0或者1,其他位为 0,(即 100001,100 这些形式),记数字位数为 len,则输出 ( len-2 ) 个 9 即可
3.数字位数为偶数,而并非是第二种情况,那么进行一次 dfs 即可
dfs 中,记处理到第 id 位,进行如下两种情况的匹配
1.ans[id] = s[id],此时要继续进行为 id+1 位的dfs。
2.ans[id] < s[id],此时在区间 [0,s[id]-1] 中从大到小寻找合适值,如果找到,那么答案串的 1~id 位已经确定, 而余下的 id+1~len 位可以从前面推导得到,所以不用继续进行 dfs。
dfs部分代码如下(预处理中我已经将读入串s整体值减一)
bool dfs(int id) { if(id==len+1) return true; bool flag; int pi,now=s[id]; //1 if(cnt[now]) cnt[now]--,ned--,ans[id]=now; else cnt[now]++,ned++,ans[id]=now; if(ned<=len-id+1) { flag=dfs(id+1); if(flag) return true; } if(cnt[now]) cnt[now]--,ned--,ans[id]=-1; else cnt[now]++,ned++,ans[id]=-1; //2 while(now-1>=0) { now--; if(cnt[now]) cnt[now]--,ned--,ans[id]=now; else cnt[now]++,ned++,ans[id]=now; if(ned<=len-id+1) return true; if(cnt[now]) cnt[now]--,ned--,ans[id]=-1; else cnt[now]++,ned++,ans[id]=-1; } return false; }
好♂用的数据
7 89 88 1000 28923845 340011 1001 88 77 99 28923839 339933 99
全部代码:
#include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <cstdio> using namespace std; const int M=2e5+44; const int N=14; char str[M]; int s[M],len; int cnt[N],ned; int ans[M]; void fillAns() { int pi=len; for(int i=0;i<=9;i++) while(cnt[i]--) ans[pi--]=i; while(ans[pi]==-1) ans[pi]=9,pi--; } bool dfs(int id) { if(id==len+1) return true; bool flag; int pi,now=s[id]; //1 if(cnt[now]) cnt[now]--,ned--,ans[id]=now; else cnt[now]++,ned++,ans[id]=now; if(ned<=len-id+1) { flag=dfs(id+1); if(flag) return true; } if(cnt[now]) cnt[now]--,ned--,ans[id]=-1; else cnt[now]++,ned++,ans[id]=-1; //2 while(now-1>=0) { now--; if(cnt[now]) cnt[now]--,ned--,ans[id]=now; else cnt[now]++,ned++,ans[id]=now; if(ned<=len-id+1) return true; if(cnt[now]) cnt[now]--,ned--,ans[id]=-1; else cnt[now]++,ned++,ans[id]=-1; } return false; } void solve() { memset(cnt,0,sizeof(cnt)); ned=0; memset(ans,-1,sizeof(int)*(len+22)); dfs(1); fillAns(); for(int i=1;i<=len;i++) printf("%d",ans[i]); puts(""); } int main() { int ex0,ex1; int cas; scanf("%d",&cas); for(int icas=1;icas<=cas;icas++) { scanf("%s",str+1); len=strlen(str+1); for(int i=1;i<=len;i++) s[i]=str[i]-'0'; int pi=len; s[pi]--; while(s[pi]<0) { s[pi]+=10; pi--; s[pi]--; } ex0=ex1=0; for(int i=1;i<=len;i++) if(s[i]==0) ex0++; else if(s[i]==1) ex1++; if(s[1]==0 || (ex0+ex1==len && ex1==1)) { for(int i=1;i<=len-2;i++) printf("9"); puts(""); } else if(len&1) { for(int i=1;i<=len-1;i++) printf("9"); puts(""); } else solve(); } return 0; } /* 7 89 88 1000 28923845 340011 1001 88 77 99 28923839 339933 99 */