Problem opisan u zadatku se može iskazati kao problem sastavljanja dva broja od zadatih cifara, tako da je njihov proizvod maksimalan. Neka su to brojevi A i B i neka se oni mogu napisati kao:
A=anan-1…a1a0 i B=bmbm-1…b1b0
Očigledno je da će u oba broja cifre biti poređane u nerastućem redosledu, posmatrajući počev od cifre najveće težine, odnosno:
an≥an-1≥…≥a1≥a0 i bm≥bm-1≥…≥b1≥b0
Neka su na raspolaganju cifre (bez gubljenja opštosti možemo ih posmatrati u uređenom redosledu):
ct≥ct-1≥…≥c1≥c0 (t=n+m+1)
Naš zadatak možemo posmatrati kao određivanje koja cifra pripada kom od dva broja, pošto znamo kako se cifre raspoređuju unutar jednog broja. Radi lakšeg zapisa, uvedimo da oznaka Ai,j predstavlja broj aiai-1...aj+1aj i analognu oznaku Bi,j.
Očigledno, najveća data cifra mora biti cifra najveće težine jednog od ova dva broja. Neka je to broj A. Dakle, ct≥an. Pokušajmo da utvrdimo kom broju pripada cifra ct-1. Postoje dve mogućnosti: ct-1≥bm ili ct-1≥an-1. Dokazaćemo da je ct-1≥bm. Pretpostavimo suprotno, tj. da je ct-1≥an-1. Tada je proizvod brojeva A i B:
AB(1)=(ct10n+ct-110n-1+An-2,0) (bm10m+Bm-1,0)=ctbm10n+m+ct10nBm-1,0+ct-1bm10n+m-1+ct-110n-1Bm-1,0+An-2,0bm10m+An-2,0Bm-1,0
Ako bi cifre an-1 i bm zamenile mesta, dobili bismo proizvod:
AB(2)=(ct10n+bm10n-1+An-2,0) (ct-110m+Bm-1,0)=ctct-110n+m+ct10nBm-1,0+bmct-110n+m-1+bm10n-1Bm-1,0+An-2,0ct-110m+An-2,0Bm-1,0
Razliku ovih proizvoda možemo pisati kao:
AB(2) – AB(1)=ct10n+m(ct-1-bm)+10n-1Bm-1,0(bm-ct-1)+An-2,010m(ct-1-bm)
=(ct-1-bm) (ct10n+m-10n-1Bm-1,0+10mAn-2,0)
S obzirom na to što je ct-1≥bm, izraz u prvoj zagradi je nenegativan. Ako je ct≥0, onda je i Bm-1,0≥0 (nijedna cifra u B nije veća od ct), pa je i izraz u drugoj zagradi nenegativan (tačnije jednak 0). Ako je ct > 0, onda je ct10n+m≥10n+m, a pošto iz Bm-1,0 < 10m sledi 10n-1Bm-1,0 < 10n+m-1, tada je ct10n+m-10n-1Bm-1,0>10n+m-10n+m-1 > 0, pa je i u ovom slučaju izraz u drugoj zagradi nenegativan (u ovom slučaju strogo pozitivan). Time smo dokazali da uvek važi:
AB(2) – AB(1)≥0
Samo za ct-1=bm važi znak jednakosti. Za ct-1 > bm važi da je AB(2) – AB(1) > 0, što je kontradikcija našem izboru lokacije za cifru ct-1. Dakle, potrebno je odabrati ct-1≥bm.
Pretpostavimo da smo rasporedili cifre ct,...,ck+1 među ciframa an,...,ai+1,bm,...,bj+1 (t – k=n – i+m – j). Za cifru ck mora važiti ck≥bj ili ck≥ai. Ukoliko je An,i+1 ≥ Bm,j+1, prethodni izbor je proizvoljan (zbog simetrije). U suprotnom, bez gubljenja opštosti, pretpostavimo da je An,i+1> Bm,j+1. Dokazaćemo da je tada ck≥bj. Pretpostavimo suprotno, tj. da je ck≥ai. Tada je proizvod brojeva A i B:
AB(1)=(An,i+110i+1+ck10i+Ai-1,0) (Bm,j+110j+1+bj10j+Bj-1,0)
=An,i+1Bm,j+110i+j+2+An,i+1bj10i+j+1+An,i+1Bj-1,010i+1+ckBm,j+110i+j+1+ckbj10i+j+
ckBj-1,010i+Ai-1,0Bm,j+110j+1+Ai-1,0bj10j+Ai-1,0Bj-1,0
Ako bi cifre ai i bj zamenile mesta, dobili bismo proizvod:
AB(1)=(An,i+110i+1+bj10i+Ai-1,0) (Bm,j+110j+1+ck10j+Bj-1,0)
=An,i+1Bm,j+110i+j+2+An,i+1ck10i+j+1+An,i+1Bj-1,010i+1+bjBm,j+110i+j+1+bjck10i+j+
bjBj-1,010i+Ai-1,0Bm,j+110j+1+Ai-1,0ck10j+Ai-1,0Bj-1,0
Razliku ovih proizvoda možemo pisati kao:
AB(2)-AB(1)=An,i+110i+j+1(ck-bj)+Bm,j+110i+j+1(bj-ck)+Bj-1,010i(bj-ck)+Ai-1,010j(ck-bj)
=(ck – bj) (An,i+110i+j+1-Bm,j+110i+j+1 - Bj-1,010i+Ai-1,010j)
S obzirom na to što je ck≥bj, izraz u prvoj zagradi je nenegativan. S obzirom na to što je An,i+1>Bm,j+1, važi:
An,i+110i+j+1-Bm,j+110i+j+1=(An,i+1-Bm,j+1)10i+j+1≥10i+j+1
S druge strane je Bj-1,0 < 10j, pa je Bj-1,010i < 10i+j. Odatle je
An,i+110i+j+1-Bm,j+110i+j+1-Bj-1,010i > 10i+j+1-10i+j > 0,
pa je izraz u drugoj zagradi pozitivan. Time smo dokazali da uvek važi:
AB(2) – AB(1)≥0
Samo za ck=bj važi znak jednakosti. Za ck>bj važi da je AB(2) – AB(1) > 0, što je kontradikcija našem izboru lokacije za cifru ck. Dakle, potrebno je odabrati ck≥bj.
Sada možemo sastaviti algoritam:
sortirati niz cifara c u opadajući poredak c[t]≥c[t-1]≥…≥c[1]≥c[0];
A=c[t]t;
B=c[t-1];
za svako i od t-2 do 0 uraditi:
ako je A≥B, dopisati cifru c[i] broju B sa desne strane;
u suprotnom, dopisati cifru c[i] broju A sa desne strane;
D=A * B;
rezultat=D mod 10^(broj cifara ispisa)
dopisati odgovarajući broj nula rezultatu sa leve strane
Nakon raspoređivanja cifara ct i ct-1 važi A≥B i cifra ct-2 će biti dopisana broju B, a potom će cifra ct-3 biti dopisana broju A pošto je broj B veći jer ima veći broj cifara (napomena: A će biti veći ako je ct > 0, a ct-1≥0, ali tada su i sve cifre nadalje jednake 0 i svejedno je kom broju se dopisuju). Nakon raspoređivanja cifara ct-2 i ct-3, brojevi A i B će imati isti broj cifara. Ako posmatramo naredne dve cifre (ct-4 i ct-5), ct-4 će biti dopisana manjem (ili jednakom) broju, a ct-5 onom drugom broju. Na taj način, proces dopisivanja cifara možemo raditi u parovima (osim eventualno poslednje cifre).
Pogodno je da relaciju između brojeva A i B određujemo iterativno nakon svakog para cifara, dakle samo na osnovu dopisanih cifara. To možemo uraditi uvođenjem logicke premenljive jednaki koja ima vrednost true dok god su brojevi A i B jednaki, pri čemu vodimo računa da u slučaju nejednakosti uvek znamo koji je broj veći (recimo A).
Takođe, nije pogodno množenje brojeva A i B, jer oni mogu biti jako veliki i, s obzirom na to što je algoritam množenja velikih brojeva kvadratne složenosti poo broju njihovih cifara, vreme izvršenja ovog algoritma bilo bi jako veliko. Međutim, s obzirom na to što je potrebno odrediti samo zadnjih M≤8 cifara proizvoda, dovoljno je pomnožiti poslednjih M cifara brojeva A i B, odnosno naći poslednjih M cifara tog proizvoda. Zgodno je, prilikom množenja, sve operacije obavljati po modulu 10m. Direktno množenje brojeva AM-1,0 i BM-1,0 premašuje opseg 32-bitnog celobrojnog tipa. To nas navodi na množenje jednog od ova dva broja, recimo AM-1,0, ciframa drugog broja, pri čemu se sve operacije obavljaju po modulu 10m.
Konačno, algoritam se može napisati ovako:
sortirati niz cifara c u opadajući poredak c[t]≥c[t-1]≥…≥c[1]≥c[0];
A=c[t];
B=c[t-1];
ako je c[t]=c[t-1], jednaki=true;
u suprotnom, jednaki=false i veciJeA=true;
za svako i od t-2 do 0 sa korakom 2 uraditi:
ako je jednaki=true, uraditi sledeće:
dopisati cifru c[i] broju A sa desne strane;
ako je i-1≥0 uraditi:
dopisati cifru c[i-1] broju B sa desne strane;
ako je c[i]>c[i-1], jednaki=false;
u suprotnom (jednaki=false), uraditi sledeće:
dopisati cifru c[i] broju B sa desne strane;
ako je i-1≥0, dopisati cifru c[i-1] broju A sa desne strane;
ako je n≥M-1, ApoModulu=A[M-1,0];
u suprtnom, ApoModulu=A;
rezultat=0;
za svako i od min(M-1, m) do 0 uraditi:
rezultat=( 10 * rezultat+ApoModulu * B[i,i] ) mod 10^m
dopisati odgovarajući broj nula rezultatu sa leve strane