1 条题解
-
0oistream (oistream) LV 8 MOD @ 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