Hướng dẫn giải của Bội số chung nhỏ nhất (Version 2)
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
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 flashmt
const fi=''; fo=''; maxn=3500; maxp=50; base=100000; digit=5; type bignum=array[0..21] of longint; var n:longint; p:array[0..maxp] of longint; f:array[0..maxn,0..maxp] of bignum; re:array[0..maxn] of bignum; procedure rf; begin assign(input,fi); reset(input); assign(output,fo); rewrite(Output); end; procedure prime; var i,j,t:longint; begin for i:=2 to 200 do begin t:=0; for j:=2 to trunc(sqrt(i)) do if i mod j=0 then inc(t); if t=0 then begin inc(p[0]); p[p[0]]:=i; end; end; end; function small(x,y:bignum):boolean; var i:longint; begin small:=true; if x[0]<y[0] then exit; if x[0]>y[0] then begin small:=false; exit; end; for i:=x[0] downto 1 do begin if x[i]<y[i] then exit; if x[i]>y[i] then begin small:=false; exit; end; end; end; procedure put(var x:bignum;y:bignum); var i:longint; begin for i:=0 to y[0] do x[i]:=y[i]; end; procedure multi(var x:bignum;y:bignum;z:longint); var i,mem,max,t:longint; begin mem:=0; max:=y[0]; for i:=1 to max do begin t:=y[i]*z+mem; x[i]:=t mod base; mem:=t div base; end; if mem>0 then begin inc(max); x[max]:=mem; end; x[0]:=max; end; procedure pr; var i,j,t:longint; u:bignum; begin prime; for i:=0 to maxn do begin f[i,0,0]:=1; f[i,0,1]:=1; re[i,0]:=1; end; for i:=0 to maxp do begin f[0,i,0]:=1; f[0,i,1]:=1; end; for i:=1 to maxn do for j:=1 to maxp do begin if (p[j]>i) or (p[j]=0) then break; if small(f[i-1,j],f[i,j-1]) then put(f[i,j],f[i,j-1]) else put(f[i,j],f[i-1,j]); fillchar(t,sizeof(t),0); t:=p[j]; while t<=i do begin multi(u,f[i-t,j-1],t); if small(f[i,j],u) then put(f[i,j],u); t:=t*p[j]; end; if small(re[i],f[i,j]) then put(re[i],f[i,j]); end; end; procedure wf; var i,j,t,k,u:longint; s:string; begin readln(t); for i:=1 to t do begin readln(n); for j:=re[n,0] downto 1 do begin if j<re[n,0] then begin str(re[n,j],s); k:=length(s); for u:=k+1 to digit do write(0); end; write(re[n,j]); end; writeln; end; close(input); close(output); end; begin rf; pr; wf; end.
Code mẫu của ladpro98
#include <bits/stdc++.h> const int N = 3505; const int BASE = 100000; const int LENGTH = 5; using namespace std; typedef vector<int> bigInt; void fix(bigInt &a) { a.push_back(0); for (int i = 0; i + 1 < a.size(); ++i) a[i + 1] += a[i] / BASE, a[i] %= BASE; while (a.size() > 1 && a.back() == 0) a.pop_back(); } void operator *= (bigInt &a, int b) { for (int i = 0; i < a.size(); ++i) a[i] *= b; fix(a); } bigInt operator * (bigInt a, int b) { a *= b; return a; } ostream& operator << (ostream& cout, const bigInt &a) { cout << a.back(); for (int i = int(a.size()) - 2; i >= 0; --i) cout << setw(LENGTH) << setfill('0') << a[i]; return cout; } bool operator < (bigInt &a, bigInt &b) { if (a.size() != b.size()) return a.size() < b.size(); for (int i = a.size() - 1; i >= 0; --i) if (a[i] != b[i]) return a[i] < b[i]; return 0; } bool isPrime[N]; int P[N]; int nPrime; bigInt dp[N][N]; void sieve() { memset(isPrime, 1, sizeof(isPrime)); for (int i = 2; i * i < N; ++i) if (isPrime[i]) { for (int j = i * i; j < N; j += i) isPrime[j] = 0; } for (int i = 2; i < N; ++i) if (isPrime[i]) P[++nPrime] = i; } void update(int nxtI, int nxtJ, int i, int j, bigInt &target) { if (dp[nxtI][nxtJ] < target) dp[nxtI][nxtJ] = target; } void preCalc() { nPrime = 100; for (int i = 0; i < N; ++i) dp[i][0] = bigInt(1, 1); for (int i = 1; i <= nPrime; ++i) dp[P[i]][i] = bigInt(1, P[i]); bigInt temp; for (int i = 0; i < N; ++i) for (int j = 0; j < nPrime && P[j] <= i; ++j) { update(i, j + 1, i, j, dp[i][j]); for (int p = 1; i + p < N; p *= P[j + 1]) { temp = dp[i][j] * p; update(i + p, j + 1, i, j, temp); } } } void solve() { int n; cin >> n; bigInt ans (1, 0); for (int i = 0; i <= nPrime && P[i] <= n; ++i) if (ans < dp[n][i]) ans = dp[n][i]; cout << ans << '\n'; } int main() { ios::sync_with_stdio(0); cin.tie(0); sieve(); preCalc(); int nTest; cin >> nTest; while (nTest--) solve(); return 0; }
Code mẫu của RR
//Written by RR {$R-,Q-} {$Mode objfpc} {$inline on} uses math; const FINP = ''; FOUT = ''; MAXN = 3535; base = 100000000; lbase = 8; type big = array[0..10] of longint; operator > (a,b:big) c:boolean; var i:longint; begin if a[0]>b[0] then exit(true) else if a[0]<b[0] then exit(false); for i:=a[0] downto 1 do if a[i]>b[i] then exit(true) else if a[i]<b[i] then exit(false); exit(false); end; operator * (a:big; k:longint) c:big; var i,nho:longint; x:int64; begin fillchar(c,sizeof(c),0); c[0]:=a[0]; nho:=0; for i:=1 to c[0] do begin x:=int64(a[i])*k+nho; nho:=x div base; c[i]:=x mod base; end; if nho>0 then begin inc(c[0]); c[c[0]]:=nho; end; end; var f1,f2 : text; procedure print(var a:big); var c,i,j,x:longint; begin write(f2,a[a[0]]); for i:=a[0]-1 downto 1 do begin c:=0; x:=a[i]; while (x>0) do begin inc(c); x:=x div 10; end; for j:=1 to lbase-c do write(f2,'0'); write(f2,a[i]); end; writeln(f2); end; var n : longint; f : array[0..MAXN,0..500] of big; tmp : big; procedure openF; begin assign(f1,FINP); reset(f1); assign(f2,FOUT); rewrite(f2); end; procedure closeF; begin close(f1); close(f2); end; const MAXV = 3500; MAXP = trunc((MAXV/ln(MAXV))*200/100); var dd : array[1..MAXV] of byte; prime : array[1..MAXP] of longint; sprime : longint; procedure generate; var i,j,gh:longint; begin gh:=trunc(sqrt(MAXV)); for i:=2 to gh do if dd[i]=0 then begin inc(sprime); prime[sprime]:=i; j:=i*i; while j<=MAXV do begin dd[j]:=1; inc(j,i); end; end; for i:=gh+1 to MAXV do if dd[i]=0 then begin inc(sprime); prime[sprime]:=i; end; end; procedure init; var i,k:longint; p:int64; begin for i:=0 to sprime do begin f[1,i][0]:=1; f[1,i][1]:=1; f[0,i]:=f[1,i]; end; for i:=2 to 3500 do begin f[i,0]:=f[1,1]; for k:=1 to sprime do begin f[i,k]:=f[i,k-1]; p:=prime[k]; while p<=i do begin tmp:=f[i-p,k-1]*p; if tmp>f[i,k] then f[i,k]:=tmp; p:=p*prime[k]; end; end; end; end; var test:longint; begin openF; generate; init; read(f1,test); for test:=1 to test do begin read(f1,n); print(f[n,sprime]); end; closeF; end.
Code mẫu của hieult
#include <cstdio> #include <iostream> #include <cstring> //#include <conio.h> #include <cmath> #define base 1000000000 using namespace std; struct solon { int so; long long a[10]; solon(){so = 1; a[1] = 0;} solon(long long x){so = 1; a[1] = x;} }; solon f[3601][505]; solon Khong = solon(0); int u[600],t=1; solon Max; int sosanh(int u,int v){ if(f[u][v].so > Max.so) return 1; if(f[u][v].so < Max.so) return -1; for(int i = Max.so;i>=1;i--){ if(f[u][v].a[i] > Max.a[i]) return 1; if(f[u][v].a[i] < Max.a[i]) return -1; } return 0; } solon tong (solon A,solon B) { int du = 0; solon C; if(A.so<B.so) { C = A; A = B; B = C; } for(int i = B.so+1;i<=A.so;i++) B.a[i] = 0; C.so = A.so; for(int i = 1;i<=A.so;i++) { C.a[i] = (A.a[i]+B.a[i]+du)%base; du = (A.a[i]+B.a[i]+du)/base; } if(du>0) {C.so++; C.a[C.so] = du;} return C; } solon tichnho(solon A,long long k,int chuso) { solon C; long long du = 0; C.so = A.so+chuso; for(int i = 1;i<=chuso;i++) C.a[i] = 0; for(int i = chuso+1;i<=chuso+A.so;i++) { C.a[i] = (A.a[i-chuso]*k+du)%base; du = (A.a[i-chuso]*k+du)/base; } if(du>0) {C.so++; C.a[C.so] = du;} return C; } solon tich(solon A,solon B) { solon C; C.so = 1; C.a[1] = 0; for(int i = 1;i<=B.so;i++) { C = tong(C,tichnho(A,B.a[i],i-1)); } return C; } void print(solon A) { printf("%lld",A.a[A.so]); for(int i = A.so-1;i>=1;i--) printf("%09lld",A.a[i]); } solon hieu(solon A,solon B){ solon C; C.so = A.so; for(int i = B.so+1;i<=A.so;i++) B.a[i] = 0; int du = 0; for(int i = 1;i<=A.so;i++){ C.a[i] = A.a[i]-B.a[i]-du; if(C.a[i]<0){ C.a[i]+=base; du = 1; } } while(C.a[C.so]==0) C.so--; if(C.so==0) C.so = 1; } solon chia2(solon A){ int du = 0; long long x; for(int i = A.so;i>=1;i--){ x = A.a[i]; A.a[i] = (x+du*base)/2; du = x%2; } if(A.a[A.so]==0) A.so--; if(A.so==0) A.so++; return A; } int main() { // freopen("input.in","r",stdin); // freopen("output.out","w",stdout); u[1] = 2; for(int i = 3;i<=3600;i++) { int flag = 0; for(int j = 1;;j++) { if(u[j]>sqrt(i)) break; else if(i%u[j]==0) { flag=1; break; } } if(flag==0) { t++; u[t]=i; } } //printf("%d",u[t]); for(int j = 0;j<=t;j++) f[0][j] = solon(1); //printf("?\n"); for(int i = 1;i<=3500;i++) { for(int j = 1;;j++) { if(u[j]>i) break; else { Max = solon(0); if(sosanh(i - 1, j)>0 ) Max = f[i-1][j]; if(sosanh(i ,j - 1)>0) Max = f[i][j-1]; int T = u[j]; while(i-T>=0) { // solon X; solon X = tichnho(f[i-T][j-1],T,0); if(X.so > Max.so) Max = X; else if(X.so == Max.so){ for(int k = X.so; k >=1; k--) if(X.a[k] > Max.a[k]){ Max = X; break; } else if(X.a[k] < Max.a[k]) break; } T=T*u[j]; } f[i][j]=Max; } } } //printf("fn\n"); int test,n; scanf("%d",&test); for(int ii = 1;ii<=test;ii++) { scanf("%d",&n); if(n==1) printf("1\n"); else { Max = solon(0); for(int i = 1;i<=t;i++) { if(sosanh(n ,i)>0) Max=f[n][i]; } print(Max); printf("\n"); } } //getch(); }
Code mẫu của ll931110
{$MODE DELPHI,N+} program CTNOWN; const input = ''; output = ''; maxn = 3500; maxk = 500; maxd = 15; base = 1000000; maxv = 1000000; var F: array[0..maxn,0..maxk] of extended; trace: array[0..maxn,0..maxk] of integer; d: array[1..maxd] of integer; list: array[1..maxk] of integer; fi,fo: text; n,nlist: integer; i,nTest: integer; procedure openfile; begin assign(fi, input); reset(fi); assign(fo, output); rewrite(fo); end; function prime(x: integer): boolean; var i: integer; begin for i := 2 to trunc(sqrt(x)) do if x mod i = 0 then exit(false); prime := true; end; procedure solve; var i,j,t: integer; begin nlist := 0; for i := 2 to maxn do if prime(i) then begin inc(nlist); list[nlist] := i; end; fillchar(F, sizeof(F), 0); for j := 1 to nlist do for i := 2 to maxn do begin F[i,j] := F[i,j - 1]; trace[i,j] := i; t := list[j]; while i >= t do begin if F[i,j] < F[i - t,j - 1] + ln(t) then begin F[i,j] := F[i - t,j - 1] + ln(t); trace[i,j] := i - t; end; t := t * list[j]; end; end; end; procedure mul(x: integer); var i: integer; begin if x = 0 then exit; for i := 1 to maxd do d[i] := d[i] * x; for i := 1 to maxd - 1 do if d[i] >= base then begin d[i + 1] := d[i + 1] + d[i] div base; d[i] := d[i] mod base; end; end; procedure printresult; var i,u,k,s,tmp: integer; st: string; max: extended; begin readln(fi, n); max := 0; u := 0; for i := 1 to maxk do if max < F[n,i] then begin max := F[n,i]; u := i; end; fillchar(d, sizeof(d), 0); d[1] := 1; s := n; for k := u downto 1 do begin tmp := trace[s,k]; mul(s - tmp); s := tmp; end; s := maxd; while d[s] = 0 do dec(s); write(fo, d[s]); for i := s - 1 downto 1 do begin str(d[i],st); for k := 1 to 6 - length(st) do write(fo, 0); write(fo, st); end; writeln(fo); end; procedure closefile; begin close(fo); close(fi); end; begin openfile; solve; readln(fi, nTest); for i := 1 to nTest do printresult; closefile; end.
Code mẫu của khuc_tuan
#include <iostream> #include <cstdio> using namespace std; const int COSO = 10000; struct BigInt { int a[20]; void assign(int x) { a[0] = x; for(int i=1;i<20;++i) a[i] = 0; } void viet() { for(int i=20-1;i>=0;--i) if(a[i] > 0) { printf("%d",a[i]); for(int j=i-1;j>=0;--j) printf("%04d",a[j]); break; } } BigInt opMul(int x){ BigInt b; int nho = 0; for(int i=0;i<20;++i) { nho += a[i] * x; b.a[i] = nho % COSO; nho /= COSO; } return b; } int opCmp(BigInt b) { for(int i=20-1;i>=0;--i) { if(a[i] < b.a[i]) return -1; if(a[i] > b.a[i]) return 1; } return 0; } }; const int MAXN = 3550; BigInt F[MAXN][300]; int prime[1000]; int main() { int nprime = 0; for(int i=2;i<300;++i) { bool isprime = true; for(int j=2;j*j<=i;++j) if(i % j == 0) { isprime = false; break; } if(isprime) prime[nprime++] = i; } for(int i=0;i<MAXN;++i) { if(i < 2) F[i][0].assign(1); else { int z = 2; while(2 * z <= i) z *= 2; F[i][0].assign(z); } } for(int p=1;p<nprime;++p) { for(int i=0;i<MAXN;++i) { F[i][p] = F[i][p-1]; int z = prime[p]; while(z <= i) { BigInt tmp = F[i-z][p-1] .opMul( z ); if(F[i][p] .opCmp( tmp ) < 0) { F[i][p] = tmp; } z *= prime[p]; } } } int ntest, n; scanf("%d",&ntest); for(int test=0;test<ntest;++test) { scanf("%d",&n); F[n][nprime-1].viet(); printf("\n"); } return 0; }
Bình luận