hdu 5710 digit—sum數論
阿新 • • 發佈:2018-12-18
題目連結 hdu 5710
思路題
/*竟然一道題想了兩天 對於n中的任何一個數位x,若x為0-4,則因為沒有進位, 所以在S(2n)中貢獻為2x;若x為5-9,則由於其超過10,在S(2n)中貢獻為2x-10+1. a*S=b*(2S*9L) 則 (2b-a)S=9*b*L s=9bl/(2b-a); s就是s(n),a,b就是題目中給的ab l是某一位上為5-9的 位數 1. a=2b,則L=0,S為任意值。可得最小的n=1; 2. a>2b,則L<0,矛盾!則無滿足的n,輸出0; 3. a<2b, S=9bL/(2b-a)≤5L (至少有L個5),即必須滿足 b≤5a ,否則無滿足的n,輸出0。 a趨近於0,9b/2b<10b/2b,利用了放縮 繼續討論上述第三種情況,由於分母為2b-a,L週期性地使得右邊式子可以整除,現在只要求出最小的L, 列舉範圍從1到2b-a必定會有滿足的L。 得到一組滿足的(L,S),構造最小的n。最小的n,最小的l首 先要在後L位塞滿5,剩下的(S-5L)開始從個位到高位塞4,直到塞完為止。 故 S(n)=k*(9b) , L=k*(2b-a)同時,由於要求 n 最小,可知 k 取 1 時最小。 在已有 S(n)以及 L 的情況下,求 n ? 首先構造長為 L ,每個字元均為 5 (由於 L 個數字必須 >= 5)的字串, 同時 S(n)-=5×L 。對於多餘的 S(n) , 為使得 n 儘可能小(即串長最小,大的數字儘可能向個位數靠攏)。故優先將串尾的字元增長到 9 。 若長為 L 的字串已經全部為 9 。此時不得不增加串長,則優先在串首增加 4 (不在 L 個數字中的均 <= 4),直到 S(n)S(n) 全部用盡。 */ #include<cstdio> #include<iostream> #include<algorithm> using namespace std; int main() { int t,a,b,s,l,GCD,add;//add代表加的值 scanf("%d",&t); while(t--){ scanf("%d%d",&a,&b); if(a>2*b||b>5*a) printf("0\n"); else{ l=2*b-a; s=9*b; GCD=__gcd(l,s); l/=GCD; s/=GCD; string ans=string(l,'5');//先把l裡面都換成5; s-=5*l; for(int i=ans.size()-1;i+1;i--){//要想使位數比較小,需要各位為9 add=min(s,4);//如果sn>4,5+4=9,如果小於4 ,直接 加原來的 ans[i]+=add; s-=add; } while(s){//如果變成9 還不夠,那就要把串長增加 add=min(s,4); ans=char(add+'0')+ans; s-=add; } printf("%s\n",ans.c_str()); //C語言中沒有string類,字串使用char指標來實現的。 //C與C++本身就是一家,為了讓它們在一定程度上可以通用,就有了.c_str()函式。 } } return 0; }