zoukankan      html  css  js  c++  java
  • CodeForces

    题目链接:http://codeforces.com/problemset/problem/95/B

    题意:给一个正整数n(1-100000位),求出不小于n的最小幸运。幸运数的概念是:由数量相等的4和7组成的数。

    思路:

    大体分三种情况:

    1.n的位数len为奇数,最简单就是增加一位变成len+1偶数个,前一半为4,后一半为7

    2.n的位数len为偶数,但找不到有len位数的幸运数比n大,那么就要增加两位len+2,前一半为4,后一半为7(可以和情况1放在一起)

    3.n的位数len为偶数,可以找到幸运数。这种情况就要搜索找到最小的了。

    因为数的位数过大,时间复杂度只能是O(n)或者O(nlogn)。

    这里就要用到贪心的思路了,我们搜索遍历每一位,先将能变成4的变为4,在看变为7。

    如果遍历的这位已经变大了,那么就不用考虑后面的数了,直接排。此时就是最小的

    自己太弱了,看了大佬的代码,才知道还可以这样。只要考虑<=4和<=7的情况,>7的情况不用考虑了,因为要不数值太大,没有符合的幸运数,要不是前面已经变大了不用考虑。

    我本来还有一个疑问的就是,4和7的个数不能均分怎么办比如7774。看了大佬代码才知道,开始搜索条件直接为dfs(int pos,int n4,int n7,int tag)(pos为搜索现在的位数,n4,n7为可以用的个数,tag标记已经变大了)

    直接无视了这种情况,只要呢,n4,n7的可用个数不够,直接false了。

    具体可以看代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    char s[100005];
    char ans[100005];
    int len;
    bool dfs(int pos,int n4,int n7,bool tag)//pos为当前位置,n4,n7为可用的4,7个数,tag为标记是否变大 
    {
        if(pos>=len)//搜索到最后,没有退出,那么就是该ans就是答案。这是判断n本身就是幸运数的情况 
            return true;
        if(tag)//已经变大 
        {
            for(int i=0;i<n4;i++)//后面接可用个数的4 
                ans[i+pos]='4';
            for(int i=0;i<n7;i++)//再接可用个数的e7 
                ans[i+pos+n4]='7';
            return true;
        }
        if(s[pos]<='4'&&n4)//先判断可变为4的 
        {
            if(dfs(pos+1,n4-1,n7,s[pos]<'4'))//<4在为变大,=4会继续搜索 
            {
                ans[pos]='4';
                return true;
            }
        }
        if(s[pos]<='7'&&n7)//在判断可变为7的 
        {
            if(dfs(pos+1,n4,n7-1,s[pos]<'7'))
            {
                ans[pos]='7';
                return true;
            }
        }
        return false;
    }
    int main()
    {
        while(cin>>s)
        {
            len=strlen(s);
            if(len%2==1||!dfs(0,len/2,len/2,0))
            {
                len+=1+(len%2==0);//len为奇数+1,偶数搜索不到+2 
                for(int i=0;i<len/2;i++)
                    ans[i]='4';
                for(int i=len/2;i<len;i++)
                    ans[i]='7'; 
            }
            ans[len]='';
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    TcIC(Teamcenter集成CatiaV5)的安装
    centos7上使用bind解析子域名
    Windows10 家庭版(1903/1909)中用RDPWrapper-v1.6.2和autoupdate补丁开启远程桌面功能
    修改SQL Server Express 2019 sa用户密码的方法
    微星B450主板安装64G内存的一个小招数
    缩小xfs文件系统的CentOS/RedHat虚拟机硬盘的迂回方法
    MQL命令的打开方式
    台电TBook二合一本全新安装Windows10
    django_auth_ldap
    开始认真学计算机网络----computer network学习笔记(一)
  • 原文地址:https://www.cnblogs.com/xiongtao/p/9430776.html
Copyright © 2011-2022 走看看