C++で合計がkに等しい最大面積の長方形の部分行列を見つけます
2D行列マットと値Kがあるとすると、合計がKと同じである最長の長方形の部分行列を見つける必要があります。
したがって、入力が次のような場合
2 | 8 | -5 | 6 |
-7 | 7 | 8 | -3 |
11 | -14 | 4 | 3 |
-4 | 3 | 1 | 10 |
その場合、出力は左上のポイントが(1、0)、右下のポイントが(3、2)になります。
-7 | 7 | 8 |
11 | -14 | 4 |
-4 | 3 | 1 |
これを解決するには、次の手順に従います-
-
MAX:=100
-
関数sum_k()を定義します。これには、1つの配列arr、start、end、n、k、
が必要です。 -
1つのマップを定義する
-
合計:=0、maximum_length:=0
-
初期化i:=0の場合、i
-
合計:=合計+ arr [i]
-
合計がkと同じ場合、-
-
maximum_length:=i + 1
-
start:=0
-
終了:=i
-
-
合計がマップにない場合、-
-
map [sum]:=i
-
-
(sum --k)がマップにある場合、-
-
maximum_length <(i --map [sum --k])の場合、-
-
maximum_length:=i --map [sum --k]
-
start:=map [sum --k] + 1
-
終了:=i
-
-
-
-
maximum_lengthが0でない場合はtrueを返します
-
メインの方法から、次のようにします-
-
行:=マットの行数、列:=マットの列数
-
サイズの配列温度を定義します:行。
-
配列を定義しますfinal_point={0,0,0,0}
-
maxArea:=-inf
-
左初期化の場合:=0、左
-
温度を0で埋める
-
右初期化の場合:=左、右
-
初期化i:=0の場合、i <行の場合、更新(iを1増やします)、実行-
-
temp [i]:=temp [i] + mat [i、right]
-
-
sum:=sum_k(temp、up、down、row、k)
-
エリア:=(下-上+ 1)*(右-左+ 1)
-
合計がゼロ以外でmaxArea
-
final_point [0]:=up、final_point [1]:=down
-
final_point [2]:=左、final_point [3]:=右
-
maxArea:=area
-
-
-
final_pointが[0,0,0,0]で、mat [0,0]がkでない場合、
-
「サブマトリックスが見つかりません」を返します
-
-
-
左上のポイントを表示します(final_point [0]、final_point [2])
-
右下のポイントを表示します(final_point [1]、final_point [3])
-
マット要素を表示します。
例
理解を深めるために、次の実装を見てみましょう-
#include <bits/stdc++.h> using namespace std; const int MAX = 100; bool sum_k(int arr[], int& start, int& end, int n, int k) { unordered_map<int, int> map; int sum = 0, maximum_length = 0; for (int i = 0; i < n; i++) { sum += arr[i]; if (sum == k) { maximum_length = i + 1; start = 0; end = i; } if (map.find(sum) == map.end()) map[sum] = i; if (map.find(sum - k) != map.end()) { if (maximum_length < (i - map[sum - k])) { maximum_length = i - map[sum - k]; start = map[sum - k] + 1; end = i; } } } return (maximum_length != 0); } void sum_zero(vector<vector<int>> &mat, int k) { int row = mat.size(); int col = mat[0].size(); int temp[row], area; bool sum; int up, down; vector<int> final_point = {0,0,0,0}; int maxArea = INT_MIN; for (int left = 0; left < col; left++) { memset(temp, 0, sizeof(temp)); for (int right = left; right < col; right++) { for (int i = 0; i < row; i++) temp[i] += mat[i][right]; sum = sum_k(temp, up, down, row, k); area = (down - up + 1) * (right - left + 1); if (sum && maxArea < area) { final_point[0] = up; final_point[1] = down; final_point[2] = left; final_point[3] = right; maxArea = area; } } } if (final_point[0] == 0 && final_point[1] == 0 && final_point[2] == 0 && final_point[3] == 0 && mat[0][0] != k) { cout << "No sub-matrix found"; return; } cout << "(Top, Left) Coordinate: " << "(" << final_point[0] << ", " << final_point[2] << ")" << endl; cout << "(Bottom, Right) Coordinate: " << "(" << final_point[1] << ", " << final_point[3] << ")" << endl; for (int j = final_point[0]; j <= final_point[1]; j++) { for (int i = final_point[2]; i <= final_point[3]; i++) cout << mat[j][i] << " "; cout << endl; } } main(){ vector<vector<int>> v = { { 2, 8, -5, 6 }, { -7, 7, 8, -3 }, { 11, -14, 4, 3 }, { -4, 3, 1, 10 }}; sum_zero(v, 9); }
入力
{{ 2, 8, -5, 6 }, { -7, 7, 8, -3 }, { 11, -14, 4, 3 }, { -4, 3, 1, 10 }}, 9
出力
(Top, Left) Coordinate: (1, 0) (Bottom, Right) Coordinate: (3, 2) -7 7 8 11 -14 4 -4 3 1
-
C++で楕円に内接する最大の円の領域を見つけます
長軸と短軸の長さが2aと2bの楕円があるとします。そこに内接できる最大の円の領域を見つける必要があります。したがって、a=5およびb=3の場合、面積は28.2734になります このことから、楕円に内接する最大円の半径が短軸「b」になることがわかります。したがって、面積はA=π*b * bになります。 例 #include<iostream> using namespace std; double inscribedCircleArea(double b) { double area = 3.1415 * b * b; re
-
C++で六角形に内接する最大の三角形の面積
ここでは、正六角形に内接する最大の三角形の領域が表示されます。六角形の各辺は「a」であり、三角形の各辺は「b」です。 この図から、六角形の1つの辺を使用して1つの三角形を作成すると、これらの2つの三角形が各辺を2つの部分に分割していることがわかります。 2つの直角三角形も見ることができます。ピタゴラスの公式から、次のように言うことができます- したがって、面積は- 例 #include <iostream> #include <cmath> using namespace std; float area(float a) { &nbs