切实的标题如下:(便是将多维数组的系列互换)
实际的难点如下:(便是将多维数组的种类交流)
To The Max
Problem Description
A multi-dimensional array is an array of arrays. 2-dimensional arrays
are the most commonly used. They are used to store data in a tabular
manner.
A multi-dimensional array is an array of arrays. 2-dimensional arrays
are the most commonly used. They are used to store data in a tabular
manner.
Problem Description
Given a two-dimensional array of positive and negative integers, a
sub-rectangle is any contiguous sub-array of size 1 x 1 or greater
located within the whole array. The sum of a rectangle is the sum of all
the elements in that rectangle. In this problem the sub-rectangle with
the largest sum is referred to as the maximal sub-rectangle.
Given an N*N*N cube A, whose elements are either 0 or 1. A[i, j, k]
means the number in the i-th row , j-th column and k-th layer. Initially
we have A[i, j, k] = 0 (1 <= i, j, k <= N).
We define two operations, 1: “Not” operation that we change the A[i, j,
k]=!A[i, j, k]. that means we change A[i, j, k] from 0->1,or
1->0. (x1<=i<=x2,y1<=j<=y2,z1<=k<=z2).
0: “Query” operation we want to get the value of A[i, j, k].
Consider following 2D array, which is of the size 3×53×5. For an array of size N×MN×M, the rows and columns are numbered
from 00 to N−1N−1 and columns are numbered from 00 to M−1M−1, respectively. Any element of the array
can be accessed by arr[i][j]arr[i][j] where 0≤i<N0≤i<N and 0≤j<M0≤j<M. For example, in the following
array, the value stored at arr[1][3]arr[1][3] is 1414.
Consider following 2D array, which is of the size 3×53×5. For an array of size N×MN×M, the rows and columns are numbered
from 00 to N−1N−1 and columns are numbered from 00 to M−1M−1, respectively. Any element of the array
can be accessed by arr[i][j]arr[i][j] where 0≤i<N0≤i<N and 0≤j<M0≤j<M. For example, in the following
array, the value stored at arr[1][3]arr[1][3] is 1414.
As an example, the maximal sub-rectangle of the array:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
Input
golang 代码如下:
golang 代码如下:
is in the lower left corner:
Multi-cases.
First line contains N and M, M lines follow indicating the operation
below.
Each operation contains an X, the type of operation. 1: “Not” operation
and 0: “Query” operation.
If X is 1, following x1, y1, z1, x2, y2, z2.
If X is 0, following x, y, z.
内部定义二维数组未有怎么复杂的,在赋值的长河中大家必要先定义三个一维数组 carray
:= make([]int, column, column),然后在赋值给外界的数组 array[i]
=carray
在那之中定义二维数组未有怎么复杂的,在赋值的经过中大家要求先定义2个壹维数组 carray
:= make([]int, column, column),然后在赋值给外界的数组 array[i]
=carray
9 2
-4 1
-1 8
下来正是字符串拼接和别的的语言不太一样,先定义3个var buffer
bytes.Buffer,
然后写数据buffer.WriteString(”ddd”),最终正是出口 buffer.String()
下来正是字符串拼接和其余的语言不太雷同,先定义多个var buffer
bytes.Buffer,
然后写数据buffer.WriteString(”ddd”),最终正是出口 buffer.String()
and has a sum of 15.
Output
还有正是1对数值和字符的交互转变用到了包strconv
还有正是局地数值和字符的相互调换用到了包strconv
Input
The input consists of an N x N array of integers. The input begins with
a single positive integer N on a line by itself, indicating the size of
the square two-dimensional array. This is followed by N 2 integers
separated by whitespace (spaces and newlines). These are the N 2
integers of the array, presented in row-major order. That is, all
numbers in the first row, left to right, then all numbers in the second
row, left to right, etc. N may be as large as 100. The numbers in the
array will be in the range [-127,127].
For each query output A[x, y, z] in one line. (1<=n<=100 sum of
m <=10000)
package main
import "fmt"
import "strconv"
import "bytes"
func main() {
var row,column int
fmt.Scanln(&row,&column)
var array = make([][]int,row,row)
for i:=0;i<row;i++{
carray := make([]int, column, column)
for j:=0;j<column;j++{
var columnValue string
fmt.Scan(&columnValue)
//fmt.Println(columnValue)
intv,_:= strconv.Atoi(columnValue)
carray[j] = intv
}
array[i] =carray
}
//fmt.Println(array)
var buffer bytes.Buffer
for i:=0;i<column;i++{
buffer.Reset()
for j:=0;j<row;j++{
buffer.WriteString(strconv.Itoa(array[j][i])+" ")
}
fmt.Println(buffer.String())
}
}
package main
import "fmt"
import "strconv"
import "bytes"
func main() {
var row,column int
fmt.Scanln(&row,&column)
var array = make([][]int,row,row)
for i:=0;i<row;i++{
carray := make([]int, column, column)
for j:=0;j<column;j++{
var columnValue string
fmt.Scan(&columnValue)
//fmt.Println(columnValue)
intv,_:= strconv.Atoi(columnValue)
carray[j] = intv
}
array[i] =carray
}
//fmt.Println(array)
var buffer bytes.Buffer
for i:=0;i<column;i++{
buffer.Reset()
for j:=0;j<row;j++{
buffer.WriteString(strconv.Itoa(array[j][i])+" ")
}
fmt.Println(buffer.String())
}
}
Output
Output the sum of the maximal sub-rectangle.
Sample Input
4
0 -2 -7 0 9 2 -6 2
-4 1 -4 1 -1
8 0 -2
Sample Input
Sample Output
15
难点自个儿起步用暴力法来解答,不过,通不过,超时,后来参考了弹指间别人的构思吗!没悟出那道题还足以用动归的法子解答,很震撼啊!
代码如下:
[cpp]
//这么些顺序可以求出m*n的矩阵某1块的最大值
//那种搜索算法未有不当!不过超时,由此还要越发优化算法!
//这道题的题意说的相比较模糊,标题里从未说要七个测试数据,弄得自个儿只管理了三回,导致老是一无可取,又找不到难题所在!
/*
#include<iostream>
#include<cstdio>
using namespace std;
const int MAX=10010;
多维数组,三个维度树状数组。int arr[MAX];
int main()
{
int s,max=-200;
int we=0;
int m,n;
while(scanf(“%d”,&arr[0])!=EOF)
{
//cin>>arr[0];//输入方阵的维数
m=n=arr[0];
for(int i=1;i<=arr[0]*arr[0];i++)
cin>>arr[i];
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)//那里是代表块数的大小,i*j
for(int p=1;m-p>=i-1 ;p++)
for(int q=一;n-q>=j-1;q++)//搜索路径,自上而下,自左向右
{
int cur=p+m*(q-1);
int count=0;
int temp=cur;
int temp1=1;
s=0;
//cout<<“第”<<we<<“次搜索:
“<<endl;
//cout<<“起点是
行数”<<p<<“,”<<“列数”<<q<<endl;
//cout<<“p=”<<p<<“,n=”<<n<<endl;
for(int k=1;k<=i*j;k++)
{
//cout<<arr[temp]<<” “;
s=s+arr[temp];
count++;
temp++;
if(count>=i)
{
temp=cur+temp1*m;
temp1++;
count=0;
}
}
//cout<<endl;
//we++;
if(s>max)
max=s;
}
cout<<max<<endl;
//system(“pause”);
}
return 0;
}
*/
#include<iostream>
#include<cstdio>
using namespace std;
int arr[101][101];
int sum[101],dp[101];
int main()
{
int i,j,k,p,n;
while(scanf(“%d”,&n)!=EOF)
{
int max=-200;
memset(sum,0,sizeof(sum));
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>arr[i][j];
//很难想到,那居然是1道动态规划题
//一、最大子字段和
/*
标题能够转化为五个子难题:
1,给定n个整数(或许为负数)组成的种类a[1],a[2],a[3],…,a[n],求该系列如a+a+…+a[j]的子段和的最大值。当所给的整均为负数时定义子段和为0,依此定义,所求的最优值为马克斯{0,a+a+…+a[j]},1<=i<=j<=n
我们把b[j]清楚为从眼下某项初步包涵a[j](a[j]为最终一个因素)的两次三番的段的和最大值,易知,起首的a[i]必然为正数!
记b[j]=max(a+..+a[j-1]+a[j]),当中一<=i<=j,并且1<=j<=n,须要显然的少数是b[j]的值必须带有a[j]。则所求的最大子段和为max{b[j]},1<=j<=n。
由b[j]的定义可易知,当b[j-1]>0时(即眼下的段加上a[j]那1段值会越来越大,自然把a[j]这一段接上)b[j]=b[澳门葡京备用网址 ,j-1]+a[j],不然(由于前边的段为负值,加上a[j],会使值变小,这样的话,我们将前方的段去掉,a[j]正是最大值)b[j]=a[j]。故b[j]的动态规划递归式为
b[j]=max(b[j-1]+a[j],a[j]),1<=j<=n。
二、最大子矩阵和
矩阵是二维的,将其压缩成1维就足以用地方的主意求出最大子矩阵和了
就要壹难得的数相加,压缩成壹维的就可以,大家遍历全部的回落恐怕,就足以因此地点的方法,求出最大值!
*/
for(i=0;i<n;i++)
{
memset(sum,0,sizeof(sum));
for(k=i;k<n;k++)
{
for(j=0;j<n;j++)
sum[j]=arr[k][j]+sum[j];
dp[0]=sum[0];
for(p=1;p<n;p++)
{
if (dp[p-1]>0)
dp[p]=dp[p-1]+sum[p];
else dp[p]=sum[p];
if (dp[p]>max) max=dp[p];
/*
if(dp[p-1]+sum[p]>sum[p])
dp[p]=dp[p-1]+sum[p];
else
dp[p]=dp[p-1];
if(dp[p]>max) max=dp[p];
*/
}
}
}
cout<<max<<endl;
//system(“pause”);
}
return 0;
}
2 5
1 1 1 1 1 1 1
0 1 1 1
1 1 1 1 2 2 2
0 1 1 1
0 2 2 2
Sample Output
1
0
1
三个维度树状数组。
。
加一个for循环就ok
#include <iostream>
#include <cstring>
#include <cstdio>
//#include <cmath>
#include <set>
#include <stack>
#include <cctype>
#include <algorithm>
#define lson o<<1, l, m
#define rson o<<1|1, m+1, r
using namespace std;
typedef long long LL;
const int mod = 99999997;
const int MAX = 1000000000;
const int maxn = 1005;
int n, q, x1, y1, z1, x2, y2, z2, op;
int c[101][101][101];
void add(int x, int y, int z) {
for(int i = x; i <= n; i += i&-i)
for(int j = y; j <= n; j += j&-j)
for(int k = z; k <= n; k += k&-k)
c[i][j][k]++;
}
int query(int x, int y, int z) {
int sum = 0;
for(int i = x; i > 0; i -= i&-i)
for(int j = y; j > 0; j -= j&-j)
for(int k = z; k > 0; k -= k&-k)
sum += c[i][j][k];
return sum;
}
int main()
{
//freopen("in.txt", "r", stdin);
while(cin >> n >> q) {
memset(c, 0, sizeof(c));
while(q--) {
scanf("%d%d%d%d", &op, &x1, &y1, &z1);
if(op) {
scanf("%d%d%d", &x2, &y2, &z2);
x2++, y2++, z2++;
add(x1, y1, z1);
add(x1, y1, z2);
add(x1, y2, z1);
add(x2, y1, z1);
add(x1, y2, z2);
add(x2, y1, z2);
add(x2, y2, z1);
add(x2, y2, z2);
} else printf("%d\n", query(x1, y1, z1) & 1);
}
}
return 0;
}