Editorial for Trật tự
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của RR
PROGRAM NK05ORDR; CONST fi=''; fo=''; VAR n:qword; m,k:longint; f1,f2:text; Procedure Tinh; Var a,x:qword; k1:longint; Begin k1:=k; x:=0; a:=1; While a<k do a:=a*10; repeat a:=a div 10; x:=x+(k1-a)+1; k1:=k1 div 10; until k1=0; If x>m then begin n:=0; exit; end; n:=k; If m=x then exit; a:=1; While a<k do a:=a*10; repeat If a+m-x-1<k*10 then begin n:=a+m-x-1; m:=x; end else begin k:=k*10; x:=x+k-a; a:=a*10; end; until m=x; End; Procedure Solve; Var t,i:integer; Begin Assign(f1,fi); Reset(f1); Assign(f2,fo); Rewrite(f2); Readln(f1,t); For i:=1 to t do begin Readln(f1,k,m); If k=1 then begin If m=1 then n:=1 else n:=0; end else Tinh; Writeln(f2,n); end; Close(f1); Close(f2); End; BEGIN Solve; END.
Code mẫu của khuc_tuan
const MAX_NUM = 1000000000; MAX_DIG = 30; type TDecimal = record cnt: integer; d: array[-MAX_DIG..MAX_DIG] of integer; end; procedure parse(l: longint; var d: TDecimal); var i: integer; begin for i := -MAX_DIG to MAX_DIG do d.d[i] := 0; d.cnt := 0; while l > 0 do begin d.d[d.cnt] := l mod 10; l := l div 10; inc(d.cnt); end; end; procedure add(a, b: TDecimal; var c: TDecimal); var r, i: integer; begin parse(0, c); r := 0; i := 0; while (r <> 0) or (i < a.cnt) or (i < b.cnt) do begin r := r + a.d[i] + b.d[i]; c.d[i] := r mod 10; r := r div 10; inc(i); end; c.cnt := i; end; procedure sub(a, b: TDecimal; var c: TDecimal); var r, i: integer; begin parse(0, c); r := 0; i := 0; while (r <> 0) or (i < a.cnt) or (i < b.cnt) do begin r := r + a.d[i] - b.d[i]; c.d[i] := (r + 100) mod 10; r := (r + 100) div 10 - 10; inc(i); end; c.cnt := i; end; function cmp(var a, b: TDecimal): integer; var i, j: integer; begin j := a.cnt; if b.cnt > j then j := b.cnt; for i := j - 1 downto 0 do begin if a.d[i] > b.d[i] then begin cmp := 1; exit; end else if a.d[i] < b.d[i] then begin cmp := -1; exit; end; end; cmp := 0; end; procedure println(var d: TDecimal); var i: integer; begin for i := d.cnt - 1 downto 0 do write(d.d[i]); writeln; end; var k, m, n: longint; kd, md, cd, nd, td, ad: TDecimal; i, j: integer; found: boolean; procedure process; begin { Read } read(k, m); { Init p10 } parse(k, kd); parse(m, md); { Solve } parse(1, cd); { Will use "cd" as a counter of number less that k in lex order } found := false; for i := 1 to MAX_DIG do begin { t - properly shifted k } parse(0, td); td.cnt := i; for j := 0 to kd.cnt - 1 do td.d[j - kd.cnt + td.cnt] := kd.d[j]; dec(td.d[i - 1]); { All i digit numbers smaller t are before k in lex order } add(cd, td, ad); if i < kd.cnt then begin { One more number } parse(1, td); add(ad, td, ad); end; if i >= kd.cnt then begin { We have enough digits } if cmp(cd, md) > 0 then begin { Counter is already too large -- no solution } found := false; break; end; if cmp(ad, md) >= 0 then begin { Solution is here with this number of digits } sub(md, cd, nd); nd.cnt := i; inc(nd.d[i - 1]); { Carefully check for k itself } if cmp(nd, kd) = 0 then begin { just Ok. n = k } found := true; break; end else if cmp(nd, kd) < 0 then begin { m is too small } { continue with more digits } end else begin { Ok. Larger than k } parse(1, td); sub(nd, td, nd); found := true; break; end; end; end; cd := ad; end; { Write } if found then println(nd) else writeln(0); end; var sotest, kkk : integer; begin read( sotest); for kkk:=1 to sotest do process; end.
Comments