Question link:
Http://uva.onlinejudge.org/index.php? Option = com_onlinejudge & Itemid = 8 & category = 113 & page = show_problem & problem = 1768
Original question:
A grid that wraps both horizontally and vertically is called a torus. given a torus where each cell contains an integer, determine the sub-rectangle with the largest sum. the sum of a sub-rectangle is the sum of all the elements in that rectangle. the Grid
Below shows a torus where the maximum sub-rectangle has been shaded.
1 |
-1 |
0 |
0 |
-4 |
2 |
3 |
-2 |
-3 |
2 |
4 |
1 |
-1 |
5 |
0 |
3 |
-2 |
1 |
-3 |
2 |
-3 |
2 |
4 |
1 |
-4 |
Input
The first line in the input contains the number of test cases (at most 18 ). each case starts with an integer N (1 ≤ n ≤ 75) specifying the size of the torus (always square ). then follows n lines describing the torus, each line containing N integers between-100
And 100, inclusive.
Output
For each test case, output a line containing a single INTEGER: the maximum sum of a sub-rectangle within the torus.
Sample input:
2
5
1 -1 0 0 -4
2 3 -2 -3 2
4 1 -1 5 0
3 -2 1 -3 2
-3 2 4 1 -4
3
1 2 3
4 5 6
7 8 9
Sample output:
15
45
Ideas and summary:
Is the upgraded version of the previous question (ultraviolet A 108-maximum sum. The situation has become much more complicated. This matrix can be rotated cyclically. For example, when all rows are on the rise of a row, the first row will become the last line (originally 2nd rows will become 1st rows, 3rd rows will become 2nd rows ......),
When all rows drop by a row, the last row is the first row. Similarly, columns are cyclical. turning all the "rows" into "columns" in the previous sentence is a column loop.
How can this problem be solved?
If you have done any questions related to rings before, you will immediately think of increasing the number of repeated series after the original array. For example, 1, 2, 3, and 3. After processing, it becomes 1, 2, 3, 3, 2, 2, 3. Then, this new sequence can enumerate all consecutive sequences from the ring.
Similarly, this question needs to expand the matrix and double each row of the array storing the matrix numbers and repeat the numbers, each column is also doubled. Finally, a new 2n * 2n large matrix is formed.
In the new large matrix, find the largest sum of the Child matrices whose size is less than or equal to N * n.
A restriction is added: the size of the sub-matrix must be less than or equal to N * n. Therefore, linear scanning is required for the process of "Maximum continuity and, here we need to use the monotonous queue application (previously we had a monotonous queue to find the maximum continuity and length constraints: Max
Sum of max-K-Sub-sequence ). A monotonic queue is used to maintain a minimum value with a length less than N.
Code:
/** Ultraviolet A: 10827-maximum sum on a torus * Time: 0.236 S * Author: d_double */# include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <queue> # define maxn 250 using namespace STD; struct node {int val; // value int no; // subscript}; int arr [maxn] [maxn], sum [maxn] [maxn], n, ans; inline void input () {memset (ARR, 0, sizeof (ARR); memset (sum, 0, sizeof (SUM); For (INT I = 1; I <= N; ++ I) {for (Int J = 1; J <= N; ++ J) scanf ("% d", & arr [I] [J]); For (Int J = n + 1; j <2 * n; ++ J) Arr [I] [J] = arr [I] [J-N];} For (INT I = n + 1; I <2 * n; ++ I) {for (Int J = 1; j <2 * n; ++ J) arr [I] [J] = arr [I-n] [J];} // converts for (INT I = 1; I <2 * n; ++ I) {for (Int J = 1; j <2 * n; ++ J) sum [I] [J] = arr [I] [J] + sum [I] [J-1] + sum [I-1] [J]-sum [I-1] [J-1]; }} inline void solve () {deque <node> que; node temp; int maxsum =-2147483646; For (INT I = 1; I <2 * n; ++ I) {for (Int J = (I- N> = 0? I-N: 0); j <I; ++ J) {// enumeration que. Clear (); // remember to clear it !! Int Prev = 0; For (int K = 1; k <2 * n; ++ K) {// maintain the monotonous queue while (! Que. Empty () & que. Back (). Val> PREV) que. pop_back (); While (! Que. empty () & que. front (). no <k-N) que. pop_front (); temp. val = Prev, temp. no = K-1; que. push_back (temp); int val = sum [I] [k]-sum [J] [k]-que. front (). val; If (Val> maxsum) maxsum = val; Prev = sum [I] [k]-sum [J] [k] ;}} printf ("% d \ n", maxsum) ;}int main () {int t; scanf ("% d", & T); While (t --) {scanf ("% d", & N); input (); solve ();}}
-- The meaning of life is to give it meaning.
Original
Http://blog.csdn.net/shuangde800
, By d_double (reprinted, please mark)