多维数组,三个维度树状数组

切实的标题如下:(便是将多维数组的系列互换)

实际的难点如下:(便是将多维数组的种类交流)

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:

 

澳门葡京备用网址 1

澳门葡京备用网址 2

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;
}



相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website