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.
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