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.

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

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.