链接:https://ac.nowcoder.com/acm/contest/63602/J
来源:牛客网
	
		
			    
		
	
	
                        来源:牛客网
题目描述
			          小H是大家公认的线代高手,他最近遇到了一个题,题意如下:给定长度为nnn的数组AAA和长度为mmm的数组BBB。
		
		
			          定义一个n∗mn*mn∗m的矩阵CCC, 其中Ci,jC_{i,j}Ci,j为 Ai∗BjA_i*B_jAi∗Bj ,(注意矩阵CCC不会直接给出) ,同时给出一个整数xxx, 你需要找到矩阵CCC的一个子矩阵,满足该子矩阵元素和小于等于xxx, 同时让该子矩阵的面积尽可能大。求出该子矩阵的最大面积。
		
		
			          作为线代高手的小H很快就算出了答案,那么你知道答案是多少吗?
		
		输入描述:
第一行输入两个整数nnn和mmm,分别表示数组AAA和数组BBB的长度。 第二行输入nnn个整数,表示数组AAA的元素。 第三行输入mmm个整数,表示数组BBB的元素。第四行输入一个整数xxx, 即为题目中要求的xxx。1≤n,m≤501 \leq n,m \leq 501≤n,m≤50, 1≤Ai,Bi≤501 \leq A_i,B_i \leq 501≤Ai,Bi≤50 , 1≤x≤1051 \leq x \leq 10^51≤x≤105.
输出描述:
输出一个整数 ,表示满足条件的子矩阵的最大面积。
CCC矩阵为:1 2 42 4 84 8 16元素和小于等于9的面积最大的子矩阵就是左上角2*2的矩阵,所以答案是4。
	本题给的数据范围较小,所以可以稍微暴力解法。用i和j去控制矩形的的形状范围,然后使用is_ok函数去判断当前区域里面的点和是否符合题目中的要求。最后将所有的小矩形遍历完成之后取最大值即可,注意仍需要使用二维数组前缀和来快速获取区域里面的和。
	AC代码:
#include <bits/stdc++.h>
using namespace std;
int A[55];
int B[55];
int c[55][55];
int n, m, x;
bool is_ok(int i, int j) {
    for (int x1 = 1;x1+i-1<=n;x1++) {
        for (int y1 = 1;y1+j-1<=m;y1++) {
            int x2 = x1+i-1, y2 = y1+j-1;
            if (c[x2][y2]-c[x1-1][y2]-c[x2][y1-1]+c[x1-1][y1-1]<=x) {
                return 1;
            }
        }
    }
    return 0;
}
int main() {
    cin>>n>>m;
    for (int i=1;i<=n;i++) {
        cin>>A[i];
    }
    for (int i=1;i<=m;i++) {
        cin>>B[i];
    }
    for (int i=1;i<=n;i++) {
        for (int j=1;j<=m;j++) {
            c[i][j] = A[i]*B[j];
            c[i][j] += c[i-1][j]+c[i][j-1]-c[i-1][j-1];
        }
    }
    int ans = -1;
    cin>>x;
    for (int i=n;i>0;i--) {
        for (int j=m;j>0;j--) {
            if (is_ok(i, j)) {
                if (i*j>ans) {
                    ans = i*j;
                }
            }
        }
    }
    cout<<ans;
    
    return 0;
}

 京公网安备 11010502036488号
京公网安备 11010502036488号