问题
Description
二哥在自己的后花园里种了一些花生,也快到了收获的时候了。这片花生地是一个长度为L、宽度为W的矩形,每个单位面积上花生产量都是独立的。他想知道,对于某个指定的区域大小,在这么大的矩形区域内,花生的产量最大会是多少。
Input Format
第1行有2个整数,长度L和宽度W。
第2行至第L+1行,每行有W个整数,分别表示对应的单位面积上的花生产量A( 0≤A<10)。
第L+2行有2个整数,分别是指定的区域大小的长度a和宽度b。
Output Format
输出一个整数m,表示在指定大小的区域内,花生最大产量为m。
Sample Input
4 5
1 2 3 4 5
6 7 8 0 0
0 9 2 2 3
3 0 0 0 1
3 3
Sample Output
38
样例解释
左上角:38 = (1+2+3) + (6+7+8) + (0+9+2)
数据范围
对于30%的数据: 1≤L,W≤100;
对于100%的数据: 1≤L,W≤1000。
全部区域大小满足:1≤a≤L,1≤b≤W。
解答
思路
首先想到的是循环。然后按照矩形存下所有可能的结果,比较大小留最大的即可。这个是最简单的思路。代码如下
-
import java.util.Scanner; /** * @author by zhouzhigang6 on 2018/2/3. */ public class Main1002 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int L = sc.nextInt(); int W = sc.nextInt(); int[][] s = new int[L][W]; for (int i = 0; i < L; i++) { for (int j = 0; j < W; j++) { s[i][j] = sc.nextInt(); } } int result = 0; int a = sc.nextInt(); int b = sc.nextInt(); int temp = 0; for (int m = 0; m <= L-a; m++) { for (int n = 0; n <= W-b; n++) { //求圈出的面积 for (int i = 0; i < a; i++) { for (int j = 0; j < b; j++) { temp += s[i + m][j + n]; } } if (result < temp) { result = temp; } temp = 0; } } System.out.println(result); } }
想了很多办法,甚至把循环里的if拿掉了,将temp存入ArrayList然后sort输出最大也试了。事实就是,四重循环不拿掉,就是超时。
怎么办呢?上网查!
各种都说自己是正确答案的,代码天马行空魔鬼数字没几个看得懂的,甚至看得懂的几个还是错的,java写的没看到合适的好理解的算法后,看到了一篇c++的,思路很好,设值缓存。每次求矩形时,减去第一列加上下一列,不用每次都遍历循环,去掉了一层循环。很轻松的就编译通过了。代码如下
import java.util.Scanner; public class Main1002 { static int a,b; static int[][] juxing = new int[1000][1000]; static int[] tmp = new int[1000]; public static int jisuanv(int v, int h) { int num = 0; if (h > 0) { num = tmp[v] - juxing[h-1][v] + juxing[a+h-1][v]; return num; } for (int i = h; i < a+h; i++) { num = num + juxing[i][v]; } return num; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int L = sc.nextInt(); int W = sc.nextInt(); int max = 0; int body; //将矩形各值赋值到数组 for (int i = 0; i < L; i++) { for (int j = 0; j < W; j++) { juxing[i][j] = sc.nextInt(); } } a = sc.nextInt(); b = sc.nextInt(); //圈地时。对于行,有L-a种情况 for (int i = 0; i <= L-a; i++) { body = 0; //第m列计算出每列的值赋给tmp[m],并求矩形总值body(先求第一个矩形) for (int m = 0; m < b; m++) { tmp[m] = jisuanv(m, i); body = body + tmp[m]; } if (body > max) { max = body; } //0-b,b-W构成了所有的列 //第j列计算出每列的值赋给tmp[m],并求矩形总值body(后续矩形通过减去第一列加后一列算出) for (int j = b; j < W; j++) { tmp[j] = jisuanv(j, i); body = body +tmp[j] - tmp[j-b]; if (body > max) { max = body; } } } System.out.println(max); } }
参考博客(c++算法):http://blog.youkuaiyun.com/lmw21848/article/details/51072918