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

C++のゼロ以外の部分行列の数を調べるプログラム


2つの値のみを含む行列が与えられたとします。 1と0。すべての1を含む与えられた行列の部分行列の数を見つける必要があります。値を出力として出力します。

したがって、入力が次のような場合

0 0 1 0
0 1 0 0
0 1 0 1
1 1 0 1

その場合、出力は12になります。

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

  • n:=行列のサイズ
  • m:=行列のサイズ[0]
  • サイズの配列追加を定義します:n + 1 x m+1。
  • iを初期化する場合:=0、i
  • jを初期化する場合:=0、j
  • add [i + 1、j + 1] + =matrix [i、j]
  • add [i + 1、j + 1] + =add [i、j + 1]
  • add [i + 1、j + 1] + =add [i + 1、j]
  • add [i + 1、j + 1]-=add [i、j]
  • res:=0
  • iを初期化する場合:=0、i
  • jを初期化する場合:=0、j
  • matrix [i、j]がゼロ以外の場合、-
    • 次の部分を無視し、次の反復にスキップします
  • kを初期化する場合:=1、k <=(n --i)の場合、更新(kを1つ増やす)、実行-
    • p:=0、
    • q:=m --j;
    • p <=qの場合、-
        を実行します
      • x:=(p + q)/ 2
      • a:=k * x
      • cur:=add [i + k、j + x] --add [i、j + x] --add [i + k、j] + add [i、j]
      • curがaと同じ場合、-
        • r:=x
        • p:=x + 1
      • それ以外の場合、
        • q:=x-1
    • rが0と同じ場合、-
      • ループから抜け出す
    • res:=res + r
  • return res
  • 理解を深めるために、次の実装を見てみましょう-

    #include<bits/stdc++.h>
    using namespace std;
    
    int solve(vector<vector<int>>& matrix) {
       int n = matrix.size();
       int m = matrix[0].size();
       int add[n + 1][m + 1];
       memset(add, 0, sizeof(add));
    
       for (int i = 0; i < n; i++) {
          for (int j = 0; j < m; j++) {
             add[i + 1][j + 1] += matrix[i][j];
             add[i + 1][j + 1] += add[i][j + 1];
             add[i + 1][j + 1] += add[i + 1][j];
             add[i + 1][j + 1] -= add[i][j];
          }
       }
       int res = 0;
       for (int i = 0; i < n; i++) {
          for (int j = 0; j < m; j++) {
             if (!matrix[i][j])
                continue;
             for (int k = 1; k <= (n - i); k++) {
                int p = 0,
                   q = m - j;
                int r;
                while (p <= q) {
                   int x = (p + q) / 2;
                   int a = k * x;
                   int cur = add[i + k][j + x] - add[i][j + x] - add[i + k][j] + add[i][j];
                   if (cur == a) {
                      r = x;
                      p = x + 1;
                   } else
                      q = x - 1;
                }
                if (r == 0)
                   break;
                res += r;
                }
          }
       }
       return res;
    }
    int main() {
       vector<vector<int>> mat = {{0, 0, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 1}, {1, 1, 0, 1}};
    cout<< solve(mat) <<endl;
    return 0;
    }

    入力

    {{0, 0, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 1}, {1, 1, 0, 1}}

    出力

    12

    1. グリッド内の照らされたセルの数を見つけるためのC++プログラム

      次元h*wのグリッドが与えられていると仮定します。グリッド内のセルには、球根または障害物のいずれかを含めることができます。電球のセルはそれ自体とその右、左、上、下のセルを照らし、障害物のセルが光を遮らない限り、光はセルを通して輝くことができます。障害物セルは照明できず、電球セルからの光が他のセルに到達するのを防ぎます。したがって、配列「bulb」内のグリッド内の電球セルの位置と配列「obstacles」内の障害物セルの位置を考えると、照らされているグリッド内のセルの総数を見つける必要があります。 したがって、入力がh =4、w =4、bulb ={{1、1}、{2、2}、{3、3}}、障害物

    2. パスを作成するためにグリッドでブロックするセルの数を見つけるためのC++プログラム

      次元h*wのグリッドがあるとします。セル位置(0、0)にロボットがあり、その位置(h-1、w-1)に移動する必要があります。グリッドには、ブロックされたセルとブロックされていないセルの2種類のセルがあります。ロボットはブロックされていないセルを通過できますが、ブロックされたセルを通過することはできません。ロボットは4つの方向に進むことができます。左、右、上、下に移動できます。ただし、ロボットはセルから別のセルに任意の方向に移動する可能性があるため(前のセルを無視して)、1つのパスのみを作成し、そのパスにない他のすべてのセルをブロックする必要があります。 (0、0)から(h -1、w -1)まで