Title Link: Hdu 5676
At the beginning of the problem and the number of DP-related, later discovered is the search problem, my hand forget, all super lucky number (that is, only the number 4, 7 and 4, 7 of the number of equal numbers) add up also only tens of thousands of, you can use a table to put all the super lucky Number is stored. Because the number of 4,7 must be equal, so you can use a binary number of 0, one substitution, the first limit 4,7 number is I, then is to find the 2*i bits containing I 0 and I 1 all such binary numbers, and then a simple conversion (1->7, 0->4, this way can be small to large push into the vector) to get the corresponding 4,7 number of the Super lucky Number,i from 1 to 9 (because 9*2=18 reached the upper limit of long long) to get all the super lucky numbers, After playing the table, the rest is a two-point search. At the beginning WA a pitch, later only know the need to special, because hit the largest number of tables only reached 777777777444444444 (9 4, 9 7), for a larger number than this can be directly known to be 44444444447777777777 (10 4, 10 7).
The code is as follows:
#include <cstdio>#include<cstring>#include<algorithm>#include<vector>using namespacestd;typedef unsignedLong Longull;#definefor (i,s,t) for (int i = s; I! = t; ++i)Vector<ull>luckys;ull p10[ -] = {1,Ten, };//for binary number x do a simple conversionInline ull Trans (intXintm) {ull num=0; For (J,0, m) Num+ = ((X & (1<< j))?7:4) *P10[j]; returnnum;}//the binary number of all 2*num1 bits containing NUM1 1 and NUM1 0Template <typename t>inlinevoidCalintNUM1, Vector<t> &VEC) { intMax =0, high = Num1 <<1; For (J, NUM1, high) Max|= (1<<j); intSt =0; For (J,0, NUM1) St |= (1<<j); while(St <=Max) {Vec.push_back (trans (St, High)); intx = st &-st, y = st + x;//This is a template from the challenge book, from small to large enumeration binary numbers containing a fixed number of ' 1 ' of all numbersSt = ((ST & ~y)/x >>1) |y; }}inlinevoidInitintn =9) {for (I,1, +) P10[i]= P10[i-1] *Ten; For (I,1, n +1) Cal (I, Luckys);}//template function binary find first element in VEC greater than or equal to xTemplate <typename t>inlineint_find (ConstVector<t> &vec,ConstT &x) {intMid, Low =0, up = Vec.size ()-1; while(Low <=Up ) {Mid= Low + ((Up-low) >>1); if(x < Vec[mid] | |! (Vec[mid] < x)) Up = mid-1; ElseLow = mid +1; } returnLow ;}intMain () {init (); intT; ull N; scanf ("%d", &t); while(t--) {scanf ("%llu", &N); if(N >777777777444444444) puts ("44444444447777777777");//need a special sentence Else { intID =_find (Luckys, N); printf ("%llu\n", Luckys[id]); } } return 0;}
Later on the Internet to see the next, found that can also be directly deep search to hit the table, simple and clear many:
voidDFS (ull sum,intNUM4,intnum7) { if(Num4 = =0&& Num7 = =0) {luckys.push_back (sum); return ; } if(NUM4) DFS (SUM *Ten+4, NUM4-1, NUM7); if(NUM7) DFS (SUM *Ten+7, NUM4, Num7-1);} InlinevoidInit () {for (I,1,Ten) DFS (0, I, i);}
The same is the order from small to large, the DFS does not have to be sorted after the end.
Hdu 5676 Ztr loves lucky numbers