zoukankan      html  css  js  c++  java
  • 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.数字位数为奇数,设数字位数为 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
    
    */
    

      

  • 相关阅读:
    青瓷qici
    青瓷qici
    青瓷qici
    青瓷引擎_珍膳小游戏_巧妇有好米来做煮
    2013年12月30日 星期一 谷歌、百度地图拽取
    不懂网络知识,测试工程师真的能走得很远么
    测试和开发之间的博弈--没有硝烟的战争
    docker命令每次需要sudo操作解决方案
    Ubuntu 18.04安装Docker CE + NVIDIA-Docker
    windos10下安装ubuntu18双系统
  • 原文地址:https://www.cnblogs.com/FxxL/p/8527990.html
Copyright © 2011-2022 走看看