【[Offer收割]编程练习赛13 B】最大子矩阵(自己的思路)

【题目链接】:http://hihocoder.com/contest/offers13/problem/2

【题意】

【题解】

算出1..250*250这些数字每个数字的所有因子(成对的那种,即x*y=number),这些成对的因子作为我们要枚举的矩形的长度;
当然加个限制,x<=250,y<=250;
这样1..2502里面总共也只有250个左右的因子;
可以了!
然后枚举每个格子作为矩形的右下角;
用得到的250个左右的成对因子作为矩形的长宽;
(因为要求格子的数目最多,所以在处理出因子的时候,枚举的数字从大到小枚举,这样第一次找到的符合要求的矩形就是答案了)
矩形的元素和用前缀和搞就好;

【Number Of WA

1

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define ps push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 250+10;

int n,m,k,a[N][N],b[500],num=0;
int pre[N][N];

int sum(int x1,int y1,int x2,int y2)
{
    return pre[x2][y2]-pre[x1-1][y2]-pre[x2][y1-1]+pre[x1-1][y1-1];
}

void get_yinzi(int t)
{
    for (int i = 1;i*i<=t;i++)
        if (t%i==0 && i<=250 && t/i<=250)
            b[++num] = i,b[++num]=t/i;
}

int get_ans()
{
    for (int t = 1;t<=num;t+=2)
        rep1(i,1,n)
            rep1(j,1,m)
            {
                int kuan = b[t],chang = b[t+1],x0,y0;
                x0 = i-chang+1,y0 = j-kuan+1;
                if (x0>=1 && y0>=1)
                {
                    if (sum(x0,y0,i,j)<=k) return chang*kuan;
                }
                x0 = i-kuan+1,y0 = j-chang+1;
                if (x0>=1 && y0>=1)
                {
                    if (sum(x0,y0,i,j)<=k) return chang*kuan;
                }
            }
    return -1;
}

int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    rei(n),rei(m),rei(k);
    rep1(i,1,n)
        rep1(j,1,m)
            rei(a[i][j]);
    rep1(i,1,n)
        rep1(j,1,m)
            pre[i][j] = pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];
    rep2(i,n*m,1)
        get_yinzi(i);
    cout << get_ans();
    //printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}
posted @ 2017-10-04 18:44  AWCXV  阅读(148)  评论(0)    收藏  举报