Hướng dẫn giải của VM 08 Bài 07 - Hình chữ nhật
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=501; maxc=100000000; var n,m,i,j,re,h,w,t,x,y,k:longint; a:array[1..maxn,0..maxn] of longint; procedure pr; var i,l,r,min,s,f,hx,sum:longint; begin re:=maxc; for i:=1 to n do for l:=1 to n-i+1 do begin if i>re then break; r:=l+i-1; min:=maxlongint; hx:=0; s:=1; f:=1; sum:=a[1,r]-a[1,l-1]; while (s<=f) and (f<=m) do begin if sum<k then begin f:=f+1; sum:=sum+a[f,r]-a[f,l-1]; end else begin if f-s+1<min then begin min:=f-s+1; hx:=s; end; sum:=sum-a[s,r]+a[s,l-1]; s:=s+1; end; end; if min=maxlongint then continue; if (min*i<re) then begin re:=min*i; h:=min; w:=i; x:=hx; y:=l; end; end; end; procedure wf; begin assign(output,fo); rewrite(output); if re<maxc then begin writeln(re); write(x,' ',y,' ',x+h-1,' ',y+w-1); end else write(-1); close(output); end; begin assign(input,fi); reset(input); read(m,n,k); for i:=1 to m do for j:=1 to n do begin read(t); a[i,j]:=a[i,j-1]+t; end; close(Input); pr; wf; end.
Code mẫu của happyboy99x
#include<cstdio> const int N = 501; int sum[N][N], a[N][N], m, n, k; void enter() { scanf("%d%d%d", &m, &n, &k); for(int i = 1; i <= m; ++i) for(int j = 1; j <= n; ++j) { scanf("%d", &a[i][j]); sum[i][j] = sum[i][j-1] + a[i][j]; } } void solve() { int s = m * n + 1, x0, y0, x1, y1; for(int l = 1; l <= n; ++l) for(int r = l; r <= n; ++r) { int now = sum[1][r] - sum[1][l-1]; for(int t = 1, b = 1; t <= n; ++t) { while(b <= n && now < k) ++b, now += sum[b][r] - sum[b][l-1]; if(now >= k && (r-l+1)*(b-t+1) < s) { s = (r-l+1)*(b-t+1); x0 = t; y0 = l; x1 = b; y1 = r; } now -= sum[t][r] - sum[t][l-1]; } } if(s == m * n + 1) printf("-1\n"); else printf("%d\n%d %d %d %d\n", s, x0, y0, x1, y1); } int main() { enter(); solve(); return 0; }
Code mẫu của ladpro98
program helppm; const maxn=500; fi=''; var i,j,m,n,k,lim,res,x1,y1,x2,y2,l:longint; a,col:array[0..maxn,1..maxn] of longint; f,s:array[1..maxn] of longint; sum,t,tp:longint; inp:text; begin assign(inp,fi);reset(inp); readln(inp,m,n,lim); for i:=1 to m do begin for j:=1 to n do read(inp,a[i,j]); readln(inp); end; for i:=1 to m do for j:=1 to n do col[i,j]:=col[i-1,j]+a[i,j]; for i:=1 to m do begin s[i]:=0; for j:=1 to n do inc(s[i],a[i,j]); end; res:=high(longint); for i:=1 to m do begin tp:=0; for k:=i to m do if (k-i+1<res) then begin t:=0; inc(tp,s[k]); if tp<lim then continue; for j:=1 to n do begin f[j]:=col[k,j]-col[i-1,j]; end; l:=1;j:=1;sum:=0; for j:=1 to n do begin if sum+f[j]>=lim then break; inc(sum,f[j]); end; while j<=n do begin inc(sum,f[j]); if sum-f[l]>=lim then begin while sum-f[l]>=lim do begin dec(sum,f[l]); inc(l); end; end; if sum>=lim then if res>(j-l+1)*(k-i+1) then begin res:=(j-l+1)*(k-i+1); x1:=i;x2:=k; y1:=l;y2:=j; end; inc(j); end; end else break; end; if res<>high(longint) then begin writeln(res); write(x1,' ',y1,' ',x2,' ',y2); end else write(-1); end.
Code mẫu của RR
{$R-,Q-} const FINP=''; FOUT=''; MAXN=501; var f1,f2:text; kq,lu,ld,lr,ll,m,n,k:longint; left,down,a:array[0..MAXN,0..MAXN] of longint; x:array[1..MAXN] of longint; procedure openF; inline; begin assign(f1,FINP); reset(f1); assign(f2,FOUT); rewrite(f2); end; procedure closeF; inline; begin close(f1); close(f2); end; procedure inp; inline; var i,j:longint; begin read(f1,m,n,k); for i:=1 to m do for j:=1 to n do read(f1,a[i,j]); end; procedure init; inline; var i,j:longint; begin for i:=1 to m do for j:=1 to n do down[i,j]:=down[i-1,j]+a[i,j]; for i:=1 to m do for j:=1 to n do left[i,j]:=left[i,j-1]+a[i,j]; end; var temp:longint; height,l,r,i,j,sum:longint; procedure solve1; begin kq:=maxlongint; for l:=1 to m do for r:=l to m do if r-l<kq then begin height:=r-l; for i:=1 to n do x[i]:=down[r,i]-down[l-1,i]; j:=1; sum:=x[1]; if (sum>=k) and (height<kq) then begin kq:=height; lu:=l; ld:=r; ll:=1; lr:=1; end; for i:=2 to n do begin inc(sum,x[i]); if sum>=k then begin while sum>=k do begin dec(sum,x[j]); inc(j); end; temp:=(height+1)*(i-j+2); if kq>temp then begin kq:=temp; lu:=j-1; ld:=i; ll:=l; lr:=r; end; end; end; end; end; procedure solve2; begin kq:=maxlongint; for l:=1 to n do for r:=l to n do if r-l<kq then begin height:=r-l; for i:=1 to m do x[i]:=left[i,r]-left[i,l-1]; j:=1; sum:=x[1]; if (sum>=k) and (height<kq) then begin kq:=height; lu:=l; ld:=r; ll:=1; lr:=1; end; for i:=2 to m do begin inc(sum,x[i]); if sum>=k then begin while sum>=k do begin dec(sum,x[j]); inc(j); end; temp:=(height+1)*(i-j+2); if kq>temp then begin kq:=temp; ll:=j-1; lr:=i; lu:=l; ld:=r; end; end; end; end; end; procedure ans; inline; begin if kq=maxlongint then begin writeln(f2,-1); exit; end; writeln(f2,kq); writeln(f2,ll,' ',lu,' ',lr,' ',ld); end; begin openF; inp; init; if m<n then solve1 else solve2; ans; closeF; end.
Code mẫu của hieult
#include <stdio.h> //#include <conio.h> int main() { //freopen("1.in","r",stdin); int n,m,area,a[502][502],x,x1,y1,x2,y2; long long are = 0; scanf("%d %d %d",&n,&m,&area); for(int i = 0;i<m;i++) a[0][i] = 0; for(int i = 1;i<=n;i++) { a[i][0] = 0; for(int j = 1;j<=m;j++) { scanf("%d",&x); a[i][j] = a[i][j-1]+x; are = are + x; // printf("%d ",a[i][j]); } // printf("\n"); } if(are<area) printf("-1"); else { x1 = 1;y1=1;x2 = m;y2 = n; int min = n*m; for(int i = 1;i<=n;i++) for(int j = i;j<=n;j++) { int u = 1 , v = 1;long long tong = 0; while(v<=n) { tong = tong + a[v][j] - a[v][i-1]; if(tong >=area) { if((v-u+1) * (j-i+1)<min) { min = (v-u+1) * (j-i+1); x1 = i; y1 = u; x2 = j; y2 = v; } u++; while(u<=v) { tong = tong - a[u-1][j]+a[u-1][i-1]; if(tong >=area) { if((v-u+1) * (j-i+1)<min) { min = (v-u+1) * (j-i+1); x1 = i; y1 = u; x2 = j; y2 = v; } } else break; u++; } } // printf("%d %d\n",u,v); v++; } } printf("%d\n%d %d %d %d",min,y1,x1,y2,x2); } // getch(); }
Code mẫu của ll931110
{$MODE DELPHI} {$inline on} Program HELPPM; Const input = ''; output = ''; maxn = 503; maxv = 1000000; Var a: array[0..maxn,0..maxn] of integer; m,n,k: integer; area,lx,ly,rx,ry: integer; Procedure init;inline; Var f: text; i,j: integer; Begin Assign(f, input); Reset(f); Readln(f, m, n, k); For i:= 1 to m do For j:= 1 to n do read(f, a[i,j]); Close(f); For i:= 1 to m do For j:= 2 to n do a[i,j]:= a[i,j] + a[i,j - 1]; For j:= 1 to n do For i:= 2 to m do a[i,j]:= a[i,j] + a[i - 1,j]; End; Procedure solve;inline; Var i,j,inf,sup: integer; Begin area:= maxv; For i:= 1 to n do For j:= i to n do If area > j - i + 1 then Begin inf:= 1; sup:= 1; Repeat While (a[sup,j] - a[sup,i - 1] - a[inf - 1,j] + a[inf - 1,i - 1] < k) and (sup <= m) do inc(sup); If sup > m then break; While a[sup,j] - a[sup,i - 1] - a[inf,j] + a[inf,i - 1] >= k do inc(inf); If area > (j - i + 1) * (sup - inf + 1) then Begin area:= (j - i + 1) * (sup - inf + 1); lx:= inf; ly:= i; rx:= sup; ry:= j; End; inc(sup); Until sup > m; End; End; Procedure printresult;inline; Var f: text; Begin Assign(f, output); Rewrite(f); If area = maxv then writeln(f, -1) else Begin Writeln(f, area); Writeln(f, lx, ' ', ly, ' ', rx, ' ', ry); End; Close(f); End; Begin init; solve; printresult; End.
Code mẫu của skyvn97
#include<cstdio> #define MAX 505 int a[MAX][MAX]; int s[MAX][MAX]; int k; int m,n; int res; int tx,ty,bx,by; void init(void) { scanf("%d",&m); scanf("%d",&n); scanf("%d",&k); int i,j; for (i=0;i<=m;i=i+1) s[i][0]=0; for (i=0;i<=n;i=i+1) s[0][i]=0; for (i=1;i<=m;i=i+1) for (j=1;j<=n;j=j+1) { scanf("%d",&a[i][j]); s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]+a[i][j]; } res=m*n+1; } void count(const int &b,const int &c) { int i,j; i=1;j=1; if (res<=c-b+1) return; if (s[c][n]-s[b-1][n]<k) return; while (true) { if (s[c][j]-s[c][i-1]-s[b-1][j]+s[b-1][i-1]>=k) { if (res>(c-b+1)*(j-i+1)) { res=(c-b+1)*(j-i+1); tx=b;ty=i;bx=c;by=j; } i++; } else { if (j>=n) break; else j++; } } } void process(void) { int i,j; for (i=1;i<=m;i=i+1) for (j=i;j<=m;j=j+1) count(i,j); if (res>m*n) printf("-1"); else printf("%d\n%d %d %d %d",res,tx,ty,bx,by); } int main(void) { init(); process(); return 0; }
Code mẫu của khuc_tuan
#include <stdio.h> #include <string.h> int m, n, k; int a[505][505]; long long d[505]; int main() { scanf("%d%d%d", &m, &n, &k); for(int i=0;i<m;++i) for(int j=0;j<n;++j) scanf("%d", a[i]+j); int smin = 1000000000, x, y, u, v; int inf = 1000000000; for(int i1=0;i1<m;++i1) { memset( d, 0, sizeof(d)); for(int i2=i1;i2<m;++i2) { int mm = 1000000000; int bd, kt; long long cur = 0; for(int j=0, tr=0;j<n;++j) { d[j] += a[i2][j]; cur += d[j]; while(cur-d[tr]>=k) { cur -= d[tr]; ++tr; } if(cur>=k && mm>j-tr) { mm = j - tr; bd = tr; kt = j; } } ++mm; if(mm<1000000000 && mm * (i2-i1+1) < smin) { smin = mm * (i2-i1+1); x = i1; u = i2; y = bd; v = kt; } } } if(smin==1000000000) printf("-1\n"); else printf("%d\n%d %d %d %d", smin, x+1, y+1, u+1, v+1); return 0; }
Bình luận