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.

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

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.