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

C++で黒いピクセルを囲む最小の長方形


画像があり、その画像が、0が白のピクセル、1が黒のピクセルのバイナリ行列で表されているとします。ここでは黒いピクセルが接続されているため、黒い領域は1つだけです。ピクセルは水平方向と垂直方向に接続されています。黒のピクセルの1つの位置(x、y)がある場合、すべての黒のピクセルを囲む最小の(軸に沿った)長方形の領域を見つける必要があります。

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

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

x =0、y =2の場合、出力は6になります

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

  • 1つの2Dアレイvを定義する

  • 関数searchRows()を定義します。これには、i、j、左、右、1つが必要です

  • i

    • mid:=i +(j --i)/ 2

    • k:=左

    • (k<右およびv[mid、k]は '0'と同じ)、do-

      • (kを1増やします)

    • k <'rightが1と同じ場合、-

      • j:=mid

    • それ以外の場合

      • i:=mid + 1

  • iを返す

  • 関数searchColumn()を定義します。これには、i、j、top、bottom、one、

    が必要です。
  • iがjと等しくない場合は、次のようにします-

    • mid:=i +(j --i)/ 2

    • k:=トップ

    • (k

      • (kを1増やします)

    • k

      • j:=mid

    • それ以外の場合

      • i:=mid + 1

  • iを返す

  • メインの方法から、次のようにします-

  • v:=画像

  • ret:=0

  • n:=画像の行サイズ

  • m:=画像の列サイズ

  • top:=searchRows(0、x、0、m、true)

  • 下:=searchRows(x + 1、n、0、m、false)

  • 左:=searchColumn(0、y、top、bottom、true)

  • 右:=searchColumn(y + 1、m、top、bottom、false)

  • 戻る(右-左)*(下-上)

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

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   vector < vector <char> > v;
   int searchRows(int i, int j, int left, int right, bool one){
      while (i < j) {
         int mid = i + (j - i) / 2;
         int k = left;
         while (k < right && v[mid][k] == '0')
            k++;
         if (k < right == one) {
            j = mid;
         }
         else {
            i = mid + 1;
         }
      }
      return i;
   }
   int searchColumn(int i, int j, int top, int bottom, bool one){
      while (i != j) {
         int mid = i + (j - i) / 2;
         int k = top;
         while (k < bottom && v[k][mid] == '0')
            k++;
         if (k < bottom == one) {
            j = mid;
         }
         else {
            i = mid + 1;
         }
      }
      return i;
   }
   int minArea(vector<vector<char>>& image, int x, int y) {
      v = image;
      int ret = 0;
      int n = image.size();
      int m = image[0].size();
      int top = searchRows(0, x, 0, m, true);
      int bottom = searchRows(x + 1, n, 0, m, false);
      int left = searchColumn(0, y, top, bottom, true);
      int right = searchColumn(y + 1, m, top, bottom, false);
      return (right - left) * (bottom - top);
   }
};
main(){
   Solution ob;
   vector<vector<char>> v =
   {{'0','0','1','0'},{'0','1','1','0'},{'0','1','0','0'}};
   cout << (ob.minArea(v, 0, 2));
}

入力

{{'0','0','1','0'},{'0','1','1','0'},{'0','1','0','0'}}, 0, 2

出力

6

  1. C++の長方形エリアII

    (軸に沿った)長方形のリストがあるとします。ここで、各rectangle [i] ={x1、y1、x2、y2}です。ここで、(x1、y1)は左下隅のポイントであり、(x2、y2)は右上隅のポイントです。 i番目の長方形。 平面内のすべての長方形でカバーされる総面積を見つける必要があります。答えは非常に大きい可能性があるため、モジュロ10 ^ 9+7を使用できます。 したがって、入力が次のような場合 その場合、出力は6になります。 これを解決するには、次の手順に従います- m =10 ^ 9 + 7 関数add()を定義します。これには、a、b、が必要です。 r

  2. C++の長方形領域

    2D平面内の2つの直線状の長方形で覆われる総面積を求めたいとします。ここで、各長方形は、図に示すように、左下隅と右上隅によって定義されます。 これを解決するには、次の手順に従います- =HまたはD<=Fの場合、 return(C – A)*(D – B)+(G – E)*(H – F) 配列hを定義し、A、C、E、Gをhに挿入します 配列vを定義し、B、D、F、Hをvに挿入します h配列の並べ替えとv配列の並べ替え temp:=(h [2] – h [1])*(v [2] – v [1]) 合計:=temp 合計:=合計+(C – A