Hướng dẫn giải của Phân tập


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='';
      maxs=65536;
      max=16000000;
type ar=array[0..maxs] of longint;
var n,m,m1,m2,i,j,k,sum,t,num,q,rem,temp,re:longint; dem:int64;
    a:array[0..31] of longint;
    b:array[0..15] of longint;
    p:array[0..16] of longint;
    f,g,sl:ar;
    tr:array[0..max] of longint;
    npos:longint;

procedure rf;
var i:longint;
begin
     assign(input,fi);
     reset(input);
     p[0]:=1;
     for i:=1 to 16 do p[i]:=p[i-1] shl 1;
     readln(n);
     m:=n div 2-1;
     m1:=p[m+1]-1;
     sum:=0;
     for i:=0 to m do
     begin
          read(a[i]);
          sum:=sum+a[i];
     end;
     m:=n-n div 2-1;
     for i:=0 to m do
     begin
          read(b[i]);
          sum:=sum+b[i];
     end;
     m2:=p[m+1]-1;
     close(input);
end;

procedure wf;
begin
     assign(output,fo);
     rewrite(output);
     write(re,' ',dem);
     close(output);
end;

procedure sort(l,r:longint);
var x,y,i,j:longint;
begin
     i:=l; j:=r; x:=f[(i+j) div 2];
     repeat
           while f[i]<x do i:=i+1;
           while f[j]>x do j:=j-1;
           if i<=j then
           begin
                y:=f[i]; f[i]:=f[j]; f[j]:=y;
                i:=i+1; j:=j-1;
           end;
     until i>j;
     if i<r then sort(i,r);
     if l<j then sort(l,j);
end;

function bs(x:longint;var num:longint):longint;
var l,r,m,y,re,t,u,i:longint;
begin
     l:=1; r:=npos; num:=0; y:=-1; re:=maxlongint; bs:=re;
     while l<=r do
     begin
          m:=(l+r) shr 1;
          if f[m]=x then break;
          if f[m]<x then l:=m+1
          else r:=m-1;
     end;
     if rem=0 then
     begin
          for i:=m-1 to m+1 do
              if (i>0) and (i<=npos) and (abs(f[i]-x)<re) then
              begin
                   re:=abs(f[i]-x);
                   y:=f[i];
              end;
          if y<>-1 then
          begin
               bs:=re*2;
               t:=tr[y];
               num:=sl[t];
               if re<>0 then
               begin
                    if (2*x-y<0) or (2*x-y>max) then exit;
                    t:=tr[2*x-y];
                    if t>0 then num:=num+sl[t];
               end;
          end;
     end
     else
     begin
          for i:=m-2 to m+2 do
              if (i>0) and (i<=npos) then
              begin
                   if f[i]<=x then
                   begin
                        if x-f[i]<re then
                        begin
                             re:=abs(f[i]-x);
                             y:=f[i];
                        end;
                   end
                   else
                   begin
                        if f[i]-1-x<re then
                        begin
                             re:=f[i]-x-1;
                             y:=f[i];
                        end;
                   end;
              end;
          if y<>-1 then
          begin
               bs:=2*re+1;
               t:=tr[y];
               num:=num+sl[t];
               if (2*x+1-y<0) or (2*x-y+1>max) then exit;
               t:=tr[2*x+1-y];
               if t>0 then num:=num+sl[t];
          end;
     end;
end;

begin
     rf;
     for i:=1 to m1 do
     begin
          k:=i; j:=0;
          while k>0 do
          begin
               if k and 1=1 then f[i]:=f[i]+a[j];
               j:=j+1;
               k:=k shr 1;
          end;
     end;
     sort(0,m1);

     g:=f;
     npos:=1;
     fillchar(f,sizeof(f),0);
     f[1]:=0; tr[0]:=1; sl[1]:=1;
     for i:=1 to m1 do
         if g[i]=g[i-1] then inc(sl[npos])
         else
         begin
              inc(npos);
              f[npos]:=g[i];
              tr[g[i]]:=npos;
              sl[npos]:=1;
         end;

     re:=maxlongint-10; dem:=0; q:=sum div 2; rem:=sum mod 2;
     m2:=m2 shr 1;
     for i:=0 to m2 do
     begin
          k:=i; j:=0; temp:=0;
          while k>0 do
          begin
               if k and 1=1 then temp:=temp+b[j];
               j:=j+1;
               k:=k shr 1;
          end;
          t:=bs(q-temp,num);
          if t<re then
          begin
               re:=t;
               dem:=num;
          end
          else
          begin
               if t=re then dem:=dem+num;
          end;
     end;
     wf;
end.

Code mẫu của ladpro98

program LQDDIV;
uses    math;
const   maxn=33;
        fi='';
type    pair=record
        x,y:int64;
        end;
var     n,lim,d:longint;
        res,count,sum,m:int64;
        a:array[1..maxn] of longint;
        s:array[1..1 shl (maxn shr 1)] of int64;

procedure Enter;
var     inp:text;
        i:longint;
begin
        assign(inp,fi);reset(inp);
        readln(inp,n);
        for i:=1 to n do begin
                read(inp,a[i]);
                inc(a[i],a[i]);
                inc(sum,a[i]);
        end;
        close(inp);
        lim:=n div 2;
        m:=sum div 2;
        res:=high(int64);
end;

procedure findAbs(key:int64; var p:pair);
var     l,r,m:longint;
begin
        l:=1;r:=d;
        while abs(l-r)<>1 do begin
                m:=(l+r) shr 1;
                if s[m] = key then begin
                        p.x:=s[m];p.y:=s[m];
                        exit;
                end;
                if s[m] < key then l:=m
                else r:=m;
        end;
        if abs(s[l]-key)=abs(s[r]-key) then begin
                p.x:=s[l];p.y:=s[r];
                exit;
        end;
        if abs(s[l]-key)<abs(s[r]-key) then begin
                p.x:=s[l];p.y:=s[l];
        end
        else begin
                p.x:=s[r];p.y:=s[r];
        end;
end;

function findL(key:int64):longint;
var     l,r,m,k:longint;
begin
        l:=1;r:=d;
        while l<=r do begin
                m:=(l+r) shr 1;
                if s[m]>=key then begin
                        k:=m;
                        r:=m-1;
                end
                else    l:=m+1;
        end;
        exit(k);
end;

function findR(key:int64):longint;
var     l,r,m,k:longint;
begin
        l:=1;r:=d;
        while l<=r do begin
                m:=(l+r) shr 1;
                if s[m]<=key then begin
                        k:=m;
                        l:=m+1;
                end
                else    r:=m-1;
        end;
        exit(k);
end;

procedure update(k:int64);
var     l,r:longint;
        p:int64;
        t:pair;
begin
        findAbs(m-k,t);
        p:=2*(t.x+k)-sum;
        if abs(p)<res then begin
                res:=abs(p);
                l:=findL(t.x);
                r:=findR(t.y);
                count:=r-l+1;
        end
        else
        if abs(p) = res then begin
                l:=findL(t.x);
                r:=findR(t.y);
                inc(count,r-l+1);
        end;
end;

procedure Gen(i:longint; k:int64);
begin
        if i>lim then begin
                inc(d);
                s[d]:=k;
                exit;
        end;
        Gen(i+1,k);
        Gen(i+1,k+a[i]);
end;

procedure Back(i:longint; k:int64);
begin
        if i>n then begin
                update(k);
                exit;
        end;
        back(i+1,k);
        back(i+1,k+a[i]);
end;

procedure Sort(l,r:longint);
var     i,j:longint;
        p,t:int64;
begin
        if l>=r then exit;
        i:=l;j:=r;
        p:=s[random(r-l+1)+l];
        repeat
                while s[i]<p do inc(i);
                while s[j]>p do dec(j);
                if i<=j then begin
                        if i<j then begin
                                t:=s[i];
                                s[i]:=s[j];
                                s[j]:=t;
                        end;
                        inc(i);dec(j);
                end;
        until i>j;
        Sort(l,j);sort(i,r);
end;

begin
        Enter;
        Gen(1,0);
        Sort(1,d);
        Back(lim+1,0);
        write(res div 2,' ',count div 2);
end.

Code mẫu của RR

//Written by RR
{$R+,Q+}
{$Mode objfpc}
{$inline on}
uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXN          =       33;
  MAXL          =       100111;
  sign          :       array[0..1] of longint=(-1,1);

var
  f1,f2         :       text;
  n,res,sum     :       longint;
  a             :       array[1..MAXN] of longint;
  x,e           :       array[0..1,1..MAXL] of longint;
  sl            :       array[0..1] of longint;

procedure openF;
    begin
      assign(f1,FINP); reset(f1);
      assign(f2,FOUT); rewrite(f2);
    end;

procedure closeF;
    begin
      close(f1);
      close(f2);
    end;

procedure sort(u,l,r:longint);
    var
      i,j,mid,tmp:longint;
    begin
      i:=l; j:=r; mid:=x[u,l+random(r-l+1)];
      repeat
        while x[u,i]<mid do inc(i);
        while x[u,j]>mid do dec(j);
        if i<=j then
          begin
            tmp:=x[u,i];
            x[u,i]:=x[u,j];
            x[u,j]:=tmp;
            inc(i); dec(j);
          end;
      until i>j;
      if i<r then sort(u,i,r);
      if l<j then sort(u,l,j);
    end;

procedure duyet(i,gh,k:longint);
    var
      j:longint;
    begin
      for j:=0 to 1 do
        begin
          sum:=sum+sign[j]*a[i];
          if i<gh then duyet(i+1,gh,k)
          else
            begin
              inc(sl[k]);
              x[k,sl[k]]:=sum;
            end;
          sum:=sum-sign[j]*a[i];
        end;
    end;

procedure solve;
    var
      i,j,tmp,res,count:longint;
    begin
      sum:=0;
      duyet(1,n>>1,0);
      sort(0,1,sl[0]);

      sum:=0;
      duyet(n>>1+1,n,1);
      sort(1,1,sl[1]);

      e[0,1]:=1; tmp:=1;
      for i:=2 to sl[0] do
        if x[0,i]>x[0,tmp] then
          begin
            inc(tmp);
            x[0,tmp]:=x[0,i];
            e[0,tmp]:=1;
          end
        else inc(e[0,tmp]);
      sl[0]:=tmp;

      e[1,1]:=1; tmp:=1;
      for i:=2 to sl[1] do
        if x[1,i]>x[1,tmp] then
          begin
            inc(tmp);
            x[1,tmp]:=x[1,i];
            e[1,tmp]:=1;
          end
        else inc(e[1,tmp]);
      sl[1]:=tmp;

      res:=high(longint); count:=0;
      j:=sl[1];
      for i:=1 to sl[0] do
        begin
          while (j>1) and (abs(x[1,j-1]+x[0,i])<abs(x[1,j]+x[0,i])) do dec(j);
          tmp:=abs(x[1,j]+x[0,i]);
          if tmp<res then
            begin
              res:=tmp;
              count:=e[0,i]*e[1,j];
            end
          else if tmp=res then inc(count,e[0,i]*e[1,j]);

          if j>1 then
            begin
              tmp:=abs(x[1,j-1]+x[0,i]);
              if tmp<res then
                begin
                  res:=tmp;
                  count:=e[0,i]*e[1,j-1];
                end
              else if tmp=res then inc(count,e[0,i]*e[1,j-1]);
            end;
        end;
      writeln(f2,res,' ',count div 2);
    end;

procedure inp;
    var
      i:longint;
    begin
      read(f1,n);
      for i:=1 to n do
        read(f1,a[i]);
    end;

begin
  openF;
  inp;
  solve;
  closeF;
end.

Code mẫu của hieult

#include <cstdio>
//#include <conio.h>
typedef long long ll;

void Quicksort(ll A[],ll lower,ll upper)
{
        ll x = A[(lower + upper) / 2];
        ll i = lower;
        ll j = upper;
        do{
                while(A[i] < x)
                        i ++;
                while (A[j] > x)
                        j --;
                if (i <= j)
                {
                     ll tg=A[i];
                     A[i]=A[j];
                     A[j]=tg;   
                        i ++;
                        j --;
                }
        }while(i <= j);
        if (j > lower)
                Quicksort(A, lower, j);
        if (i < upper)
                Quicksort(A, i, upper);
}  

    ll n,mu2[20],t,so,vitri;
    ll a[35],b[100000],f[100000],d[100000],tong=0,tt,max,tim,tongtim,gan;

int main()
{
    //freopen("LQDDIV1.in","r",stdin);
    scanf("%lld",&n);
    for(int i = 1;i<=n;i++) { scanf("%lld",&a[i]); tong+=a[i];}
    ll m = n/2; ll k = n-m;
    mu2[0] = 1; for(int i = 1;i<=20;i++) mu2[i] = mu2[i-1]<<1;
    for(int i = 0;i<mu2[m];i++)
    {
         gan = i; tt = 0;
         for(int j = 1;j<=m;j++){ if(gan%2==1) tt+= a[j]; gan/=2;}
         b[i+1] = tt;
    }
    //printf("%lld\n",mu2[m]);
    Quicksort(b,1,mu2[m]);
    //for(int i = 1;i<=10;i++) printf("%lld ",b[i]);
    t = 0;
    for(int i = 1;i<=mu2[m];i++)
    {
        if(i==1)
        {
             f[++t] = b[i];
             d[t] = 1;;
        }
        else
        {
            if(b[i]==b[i-1])
                 d[t]++;
            else
            {
                f[++t] = b[i];
                d[t] = 1;
            }
        }
    }
   //printf("%lld\n",tong);
    max = 0;
    for(int i = 0;i<mu2[k];i++)
    {
         gan = i; tt = 0;
         for(int j = 1;j<=k;j++){ if(gan%2==1) tt+= a[j+m]; gan/=2;}
         tim = tong/2 - tt;
         //if(i<16000&& i>=15980) printf("%lld\n",tim);
         //printf("%lld\n",tt);
         if(tim<0) continue;
         ll u = 1, v = t, r;
         while(v-u>1)
         {
            r = (u+v)/2;
            if(f[r]<=tim)
                u = r;
            else v = r;
            //if(v!=0)
         }
         //ll p1 = 45000 ,p2 = 100000;
         //if(tim == p1*p2 &&i<16000&& i>=15980) printf("%lld %lld\n",u,v);
         if(f[v]<=tim)
         {
              tongtim = f[v]+tt;
              vitri = v;
         }
         else
         {
              tongtim = f[u]+tt;
              vitri = u;
         }
         //if(tim == p1*p2 &&i<16000&& i>=15980) printf("***%lld***\n",tongtim);
         //if(tongtim%1000000000==0) printf("%lld %lld\n",u,v);
         if(tongtim > max) {max = tongtim; so = d[vitri];}
         else if(tongtim == max) {so+=d[vitri];}
    }
    //prllf("%d\n",tongtim);
    if(max*2==tong) so/=2;
    printf("%lld %lld",tong-2*max,so);
   //getch();
}

Code mẫu của ll931110

#include <iostream>
#include <cstdlib>
#define MAXV 65550
#define MAXN 33
using namespace std;

long long a[MAXV],b[MAXV],d[MAXV],kd[MAXV];
long long stmp,sum,u,delta;
int ta[MAXV],tb[MAXV],td[MAXV];
int na,nb,nd,n,tmpd,s[MAXN],k[MAXN],sup;

int compare_ints( const void* x, const void* y )
{  
     long long* arg1 = (long long*) x;
     long long* arg2 = (long long*) y;
     if( *arg1 < *arg2 ) return -1;
     else if( *arg1 == *arg2 ) return 0;
     else return 1;
}

void attempt(int i,int sup)
{
     for (int j = k[i - 1] + 1; j <= sup; j++)
     {
         k[i] = j;
         stmp += s[j];
         kd[++ nd] = stmp;

         if (j < sup) attempt(i + 1,sup);
         stmp -= s[j];
     }
}

void precalc()
{
     int i;

     nd = 0;
     stmp = 0;
     attempt(1,sup);

     qsort( kd, nd + 1, sizeof(long long), compare_ints);
     tmpd = 0;
     for (i = 0; i <= nd; i++) td[i] = 0;
     d[0] = 0;

     for (i = 0; i <= nd; i++)
       if (d[tmpd] == kd[i]) td[tmpd]++; 
       else
       {
           tmpd++;
           d[tmpd] = kd[i];
           td[tmpd] = 1;
       }
}


int main()
{
    int i,xa,xb;
    long long ncount;

    //freopen("lqddiv.inp","r",stdin);
    //freopen("lqddiv.out","w",stdout);

    scanf("%d", &n);
    sum = 0;
    for (i = 1; i <= n; i++) 
    {
        scanf("%d", &s[i]);
        sum += s[i];
    }

    sup = n/2;
    k[0] = 0;   
    precalc();
    na = tmpd;
    for (i = 0; i <= tmpd; i++) 
    {
        a[i] = d[i];
        ta[i] = td[i];
    }

    sup = n;
    k[0] = n/2;
    precalc();
    nb = tmpd;
    for (i = 0; i <= tmpd; i++) 
    {
        b[i] = d[i];
        tb[i] = td[i];
    }

    xa = 0;
    xb = nb;
    while (xb >= 0 && a[xa] + b[xb] > sum/2) xb--;      
    delta = a[xa] + b[xb];

    for (xa = 0; xa <= na; xa++)
    {
        while (xb >= 0 && a[xa] + b[xb] > sum/2) xb--;
        if (xb >= 0 && delta < a[xa] + b[xb]) delta = a[xa] + b[xb];
    }

    u = sum - 2 * delta;
    xa = 0;
    xb = nb;
    ncount = 0;

    while (xb >= 0 && a[xa] + b[xa] > delta) xb--;
    for (xa = 0; xa <= na; xa++)
    {
        while (xb >= 0 && a[xa] + b[xb] > delta) xb--;
        if (xb >= 0 && delta == a[xa] + b[xb]) ncount += ta[xa] * tb[xb];
    }

    if (u == 0) ncount = ncount/2;
    cout << u << " " << ncount;
}

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.