1 条题解

  • 0
    @ 2020-08-12 18:54:42

    输入数转成高精度存储。

    • 前两个操作:贪心+排序。
    • 第三、第四个操作:\(\text{DFS}\),可以用一个函数实现,但要注意由于数字重复,搜出来的结果可能会重复,需要在循环内部加一个判断。
    • 第五个操作:\(\text{DFS}\)。

    详细细节占坑待填。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    typedef long long Num;
    typedef unsigned long long Unum;
    typedef long double Lfloat;
    #define Rint register int
    #define It iterator
    #define Os ostream
    #define Is istream
    #define Ifs ifstream
    #define Ofs ofstream
    
    #define AK_IOI bfw
    
    template<typename T>/*T: integer type*/
    void read(T& num)
    {
        char ch;int f;num=0;while(1){ch=getchar();if(ch=='-' || (ch>='0'&&ch<='9')) break;} (ch=='-')?(f=-1):(f=1,num+=ch-'0');while(1){ch=getchar();if(!(ch=='-' || (ch>='0'&&ch<='9'))) break; num*=10;num+=ch-'0';} num*=f;
    } 
    
    /*Digits Begin*/
    
    class Digits
    {
        public: 
            Digits():theSize{0}{clear(theDigits);}
            ~Digits(){theSize=0;clear(theDigits);}
            Digits(const Num &n):theSize{0}{clear(theDigits);init(n);}
            Os& put(Os &os)
            {
                put(os,theDigits);
                return os;
            }
            inline int size() const
            {
                return theSize;
            }
            
        public:
            void smallest(int *array)
            {
                copy(theDigits,array);
            }
            Num smallest()
            {
                return toNum(theDigits);
            }
            void bigest(int *array)
            {
                copy(theDigits,array);
                reverse(array+1,array+theSize+1);
            }
            Num bigest()
            {
                reverse(theDigits+1,theDigits+theSize+1);
                Num res=toNum(theDigits);
                reverse(theDigits+1,theDigits+theSize+1);
                return res;
            }
            void kthBig(int *array,const int &k)
            {
                clear(now,-1);
                clearBool(visited);
                totalSum=0;
                reverse(theDigits+1,theDigits+theSize+1);
                findKthSmall(k,1);
                copy(now,array);
                reverse(theDigits+1,theDigits+theSize+1);
            }
            void kthSmall(int *array,const int &k)
            {
                clear(now,-1);
                clearBool(visited);
                totalSum=0;
                findKthSmall(k,1);
                copy(now,array);
            }
            Num closestNum(const Num &val)
            {
                clear(now,-1);
                ans=0ll;
                clearBool(visited);
                findClosest(val,1);
                return ans;
            }
            
        private:
            int theDigits[20];
            int theSize;
            inline void clear(int *array,const int &val=0)
            {
                for(int i=0;i<20;i++)
                {
                    array[i]=val;
                }
            }
            inline void clearBool(bool *array)
            {
                for(int i=0;i<20;i++)
                {
                    array[i]=false;
                }
            }
            inline void init(const Num &n)
            {
                Num m=n;
                while(m!=0ll)
                {
                    theDigits[++theSize]=m%10;
                    m/=10;
                }
                reverse(theDigits+1,theDigits+theSize+1);
                sort(theDigits+1,theDigits+theSize+1);
            }
            inline void copy(int *from,int *array)
            {
                for(int i=1;i<=theSize;i++)
                {
                    array[i]=from[i];
                }
            }
            Os& put(Os &os,int *array)
            {
                for(int i=1;i<=theSize;i++)
                {
                    os<<array[i]<<" ";
                }
                return os;
            }
            inline Num toNum(int *array)
            {
                Num num=0;
                for(int i=1;i<=theSize;i++)
                {
                    num*=10;
                    num+=array[i];
                }
                return num;
            }   
            
        private:
            bool visited[20];
            int now[20];
            Num ans;
            int totalSum;
            bool findKthSmall(const int &k,const int &depth)
            {
                if(depth>theSize)
                {
                    if((++totalSum)==k) 
                    {
                        return true;
                    }
                    return false;
                }
                bool succ=false;
                for(int i=1;i<=theSize;i++)
                {
                    if(visited[i]) continue;
                    if(now[depth]==theDigits[i]) continue;
                    visited[i]=true; 
                    now[depth]=theDigits[i];
                    succ|=findKthSmall(k,depth+1);
                    if(succ)
                    {
                        return true;
                    }
                    visited[i]=false;
                }
                now[depth]=-1;
                return false;
            }
            bool findClosest(const Num &k,const int &depth)
            {
                if(depth>theSize)
                {
                    Num num=toNum(now);
                    if(num>k)
                    {
                        ans=((num-k)>(k-ans))?ans:num;
                        return true;
                    }
                    ans=num;
                    return false;
                }
                bool succ=false;
                for(int i=1;i<=theSize;i++)
                {
                    if(visited[i]) continue;
                    if(now[depth]==theDigits[i]) continue;
                    visited[i]=true; 
                    now[depth]=theDigits[i];
                    succ|=findClosest(k,depth+1);
                    if(succ)
                    {
                        return true;
                    }
                    visited[i]=false;
                }
                now[depth]=-1;
                return false;
            }
            
    //      void copyNow(int *array)
    //      {
    //          for(int i=1;i<=theSize;i++)
    //          {
    //              array[i]=now[i];
    //          }
    //      }
    }; 
    
    /*Digits End*/
    
    inline Os& printNum(Os &os,int *array,const int &n)
    {
        bool flag=true;
        for(int i=1;i<=n;i++)
        {
            if(flag&(array[i]==0)){continue;}else{flag=false;}
            os<<array[i];
        }
        return os;
    }
    
    int main()
    {
        Num n;int k;
        read(n);read(k);
        
        Digits d{n};
        int a[20]={};
        Num numSmall=d.smallest();
        cout<<numSmall<<endl;
        Num numBig=d.bigest();
        cout<<numBig<<endl;
        d.kthBig(a,50);
        printNum(cout,a,d.size());cout<<endl;
        d.kthSmall(a,k);
        printNum(cout,a,d.size());cout<<endl;
        Num ave=(numSmall+numBig)/2;
        cout<<d.closestNum(ave)<<endl;
        return 0;
    }
    
  • 1

「ACSL2016-2017 All-Star」Numbers 数字

信息

ID
1118
难度
3
分类
贪心 | 排序搜索 点击显示
标签
递交数
1
已通过
1
通过率
100%
被复制
1
上传者