C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

Range Sum Query2D-C++では不変


matrixと呼ばれる2D行列があるとすると、(row1、col1)を使用して左上隅で定義され、(row1、col1)を使用して右下隅で定義される長方形内の要素の合計を見つける必要があります。 row2、col2)。

したがって、行列が-

のような場合
3 0 1 4 2
5 6 3 2 1
1 2 0 1 5
4 1 0 1 7
1 0 3 0 5

上記の長方形で、(2,1)と(4,3)で定義された青色で、合計8が含まれています。

したがって、sumRegion(2、1、4、3)、sumRegion(1、1、2、2)、sumRegion(1、2、2、4)などのクエリを実行すると、それぞれ8、11、12が返されます。

これを解決するには、次の手順に従います-

  • dpと呼ばれる行列を定義します。

  • 次のようにタスクを初期化します

  • n:=行数。 nが0の場合は、戻ります

  • m:=列数

  • dp:=サイズnxmの別の行列

  • 0からnの範囲のiの場合

    • 0からmの範囲のjの場合

      • j – 1 <0の場合、dp [i、j]をmatrix [i、j]として設定します。それ以外の場合は、これを(dp [i、j --1] + matrix [i、j])

        として設定します。
  • 1からnの範囲のiの場合

    • 0からmの範囲のjの場合

      • dp [i、j]をdp [i – 1、j]

        だけ増やします。
  • queryメソッドの場合、これにはrow1、col1、row2、col2が必要です

  • ret:=dp [row2、col2]

  • sub1:=0(row1 – 1 <0の場合)それ以外の場合はdp [row1 – 1、col2]

  • sub2:=0 col1 – 1 <0の場合、それ以外の場合はdp [row2、col1 --1]

  • row1 – 1<0またはcol1– 1 <0の場合、

    • 追加:=0

  • それ以外の場合は、:=dp [row1 – 1、col1 – 1]

    を追加します
  • return ret – sub1 – sub2 + add

例(C ++)

理解を深めるために、次の実装を見てみましょう-

#include <bits/stdc++.h>
using namespace std;
class NumMatrix {
   public:
   vector < vector <int>> dp;
   NumMatrix(vector<vector<int>>& matrix) {
      int n = matrix.size();
      if(!n) return;
      int m = matrix[0].size();
      dp = vector < vector <int>>(n, vector <int> (m));
      for(int i = 0; i < n; i++){
         for(int j = 0 ;j < m; j++){
            dp[i][j] = j - 1 < 0 ? matrix[i][j] : dp[i][j - 1] + matrix[i][j];
         }
      }
      for(int i = 1; i < n; i++){
         for(int j = 0; j < m; j++){
            dp[i][j] += dp[i - 1][j];
         }
      }
   }
   int sumRegion(int row1, int col1, int row2, int col2) {
      int ret = dp[row2][col2];
      int sub1 = row1 - 1 < 0 ? 0 : dp[row1 - 1][col2];
      int sub2 = col1 - 1 < 0 ? 0 : dp[row2][col1 - 1];
      int add = row1 - 1 < 0 || col1 - 1 < 0 ? 0 : dp[row1 - 1][col1 - 1];
      return ret - sub1 - sub2 + add;
   }
};
main(){
   vector<vector<int>> mat = {{3,0,1,4,2},{5,6,3,2,1},{1,2,0,1,5},{4,1,0,1,7},{1,0,3,0,5}};
   NumMatrix ob(mat);
   cout << ob.sumRegion(2,1,4,3) << endl;
   cout << ob.sumRegion(1,1,2,2) << endl;
   cout << ob.sumRegion(1,2,2,4) << endl;
}

入力

[[3,0,1,4,2],
[5,6,3,2,1],
[1,2,0,1,5],
[4,1,0,1,7],
[1,0,3,0,5]]
sumRegion(2,1,4,3)
sumRegion(1,1,2,2)
sumRegion(1,2,2,4)

出力

8
11
12

  1. 範囲合計クエリ-C++の不変

    整数の配列があるとします。インデックスiからjまでの要素の合計を見つける必要があります。配列は不変であるため、要素は変更されず、そのようなクエリが複数存在することに注意する必要があります。そのため、多数のクエリの実行時間を気にする必要があります。配列がA=[5、8、3、6、1、2、5]のようであるとすると、クエリが(A、0、3)の場合、5 + 8 + 3 + 6=22になります。 これを解決するには、次の手順に従います- 1つの配列Bを取得します。B[i]は0からiまでの要素の合計を格納します クエリの場合は、B [j] – B [i – 1]を実行します 理解を深めるために、次の実装

  2. C ++でのアリコートの合計?

    ここで、アリコートの合計は何ですか? nのアリコート和は、nを除くnのすべての完全な因子の合計です。たとえば、数値が20の場合、完全な因数は(1、2、4、5、10)です。したがって、アリコートの合計は22です。 興味深い事実の1つは、ある数のアリコートの合計がその数そのものである場合、その数は完全数であるということです。たとえば、6。係数は(1、2、3)です。アリコートの合計は1+2 + 3=6です。 次のアルゴリズムを使用してアリコートの合計を取得する方法を見てみましょう。 アルゴリズム getAliquotSum(n) begin    sum := 0 &nbs