ラスター化を使用せずに、つまり純粋な数値のみを使用してこれを行う方法を次に示します。
注: これは O(n log n) ではなく、O(n^2) に似ています。ただし、これは解決策です。それが答えであるかどうか、おそらく O(n log n) が要件である場合はそうではありません。
- 左端と右端のすべての一意の X 座標のリストを作成します (同じリスト内)。
- このリストを作成するときは、座標ごとに長方形のリストも関連付け、このリストで、リストが関連付けられている X 座標が長方形の左端または右端のどちらであるかを示します。
- 左から右に昇順になるように座標のリストを並べ替えます
- 長方形の新しいリストを作成します。最初は空です
- 座標のリストを実行し、関連する長方形のリストを処理します
- 関連付けられたリスト内の、座標が左端であると示されているすべての長方形を、4 で作成したリストに追加する必要があります。
- 座標を右端とするすべての長方形を削除する必要があります。
- 追加と削除の順序は、実際には逆の順序で行う必要があります。最初に右端の長方形を削除し、次にすべての左端の長方形を追加します。
- ここで、4 で作成したリストから長方形を削除する前に、それらを処理したいと考えています。それらを「サブ長方形」として処理して処理します。それらの「新しい」左端座標は、ループの前の反復 (5) で処理した X 座標であり、新しい右端は現在処理中の X 座標です。
- アルゴリズムの出力は、座標ペア (左右の 2 つの X 座標) のコレクションであり、各ペアには関連する長方形のリスト (垂直ストリップ) があります。
したがって、出力は次のようになります。
- X=1..2、長方形=A
- X=2..3、Rects=A、B
- X=3..4、Rects=A、B、C
- X=4..5、Rects=A、C
- X=5..6、長方形=C
ここまでの流れを説明します
+-------------------+
|A |
| +----------+-----+
| |C | |
| +-----+----+ | |
| |B | | | |
| | +----+-----+-----+
| | | |
+--+----------+-----+
| |
+----------+
^ ^ ^ ^ ^ ^
1 2 3 4 5 6 <-- X-coordinates
関連する長方形:
- 左:A、右:(なし)
- 左:B、右:(なし)
- 左:C、右:(なし)
- 左:(なし)、右:B
- 左:(なし)、右:A
- 左:(なし)、右:C
空のリスト を作成しL=[]
、座標と関連する四角形の処理を開始します。
X=1
リストは空です。処理するものはありません。削除するものはありません A を追加: L=[ A ]
X=2
リストには四角形が含まれ、左端が X=1、右端が X=2 (これまでに処理した 2 つの座標) の四角形としてリストを処理し、元の上部と下部の座標を使用します。削除するものはありません。B を追加: L=[ A, B ]
X=3
リストには四角形が含まれ、リスト (A と B の両方) を同じ方法で処理し、それらを一時的に左右の座標を X=2 と X=3 として扱い、元の上下の座標を使用します。削除するものはありません C を追加: L=[ A, B, C ]
X=4
上記と同じ方法で 3 つの長方形を処理します。一時的な左右の座標は X=3 と X=4 B を削除: L=[A, C ] 追加するものはありません
X=5 および X=6
これらをまったく同じ方法で処理します。
これは、次のような長方形の「ストリップ」になることを意味します (ストリップであることを明確に示すために少し引き離していますが、元の図のように連続して並んで配置されています)。
+--+ +-----+ +----+ ------+
|A | | | | | | |
| | | | +----+ +-----+ +-----+
| | | | |C | | | | |
| | +-----| +----+ | | | |
| | |B | | | | | | |
| | | | +----+ +-----| +-----+
| | | | | | | |
+--+ +-----+ +----+ +-----+
| | | |
+-----+ +----+
^ ^ ^ ^ ^ ^ ^ ^ ^ ^
1 2 2 3 3 4 4 5 5 6
わかりました。これで、座標ペアのコレクションである出力が得られました。各ペアには、関連付けられた四角形のリストがあります。
今、私たちはトリックをします。垂直ストリップをまったく同じ方法で処理しますが、今回は区切り文字として Y 座標を使用します。上記の 3 と 4 の間のストリップを処理しましょう。ストリップの左右の座標は 3 と 4 であることに注意してください。
ストリップは次のようになります。
^ +----+ <-- 1
A | |
| ^ +----+ <-- 2
| C | |
| ^ | +----+ <-- 3
| B | | |
| | V +----+ <-- 4
| | | |
V | +----+ <-- 5
| | |
V +----+ <-- 6
長方形を含む座標のリスト:
- 上=A、下=(なし)
- 上=C、下=(なし)
- 上=B、下=(なし)
- 上=(なし)、下=C
- 上=(なし)、下=A
- 上=(なし)、下=B
新しい空のリスト L=[]
座標を処理します。
Y=1
処理するものなし (L=[]) リストに A を追加、L=[ A ]
Y=2
一時的に Y=1 と 2 の上部座標と下部座標を持つプロセス A (また、X=3 と 4 の一時的な左右座標もあることに注意してください) C、L=[ A, C ] を追加します。
Y=3
プロセス A と C、両方とも (3, 2)-(4, 3) の一時座標を持ち、B を追加、L=[ A, B, C ]
Y=4
プロセス A、B、および C、すべて (3, 3)-(4, 4) の座標を持つ C を削除、L=[ A, B ]
Y=5
プロセス A と B、座標 (3, 4)-(4, 5) A を削除、L=[ B ]
Y=6
プロセス B、座標 (3, 5)-(4, 6)
最終出力:
四角形が関連付けられた Y 座標のペア (一時的に新しい X 座標も取得しています):
- (3, 1)-(4, 2) - A
- (3, 2)-(4, 3) - A, C
- (3, 3)-(4, 4) - A、B、C
- (3, 4)-(4, 5) - A, B
- (3, 5)-(4, 6) - B
ここで、次の質問をしたいとします: B は、他のすべての長方形の組み合わせによって完全に覆われていますか?
答えは次のように計算できます。
- 上記の最終リストのすべての長方形をループします
- B が関連付けられた四角形の一部でない場合、この四角形を無視します
- 座標に関連付けられた元の長方形が他にある場合、B のこの部分はその/それらの長方形によってカバーされます。
- 座標に関連付けられた元の四角形が他にない場合、B のこの部分はカバーされません。
上記の例では、最後のリストの 3 番目と 4 番目の四角形に B が含まれていますが、他の四角形も含まれているため、B のこれらの部分がカバーされていますが、リストの最後の四角形にも B が含まれていますが、他の四角形は含まれていません。したがって、この部分はカバーされていません。
元の図によると、最終結果には次のような四角形が含まれます (各内の文字は、元の四角形がこの新しい四角形に関連付けられていることを示します)。
+--+-----+----+-----+
|A |A |A |A |
| | +----+-----+-----+
| | |AC |AC |C |
| +-----+----+ | |
| |AB |ABC | | |
| | +----+-----+-----+
| | |AB |A |
+--+-----+----+-----+
|B |B |
+-----+----+
元の図をもう一度見てみると、上記のアルゴリズムで B が含まれているが、他の四角形が含まれていないことが判明した部分に網掛けが施されています。
+-------------------+
|A |
| +----------+-----+
| |C | |
| +-----+----+ | |
| |B | | | |
| | +----+-----+-----+
| | | |
+--+-----+----+-----+
|#####|####|
+-----+----+
中央の垂直バーは、垂直ストリップが作成された方法により、その位置で分割された 2 つの長方形としてパーツが返されることを示しています。
ここで自分自身を理解してくれることを真剣に願っています。座標のリストの各実行の実装に役立つコードがいくつかありますが、ここでは真夜中過ぎの 01:21 であり、就寝しますが、実際のコードを確認したい場合はコメントを残してください。 .
または、それを自分で実装するのは素晴らしい練習になるでしょう:)
問題のメソッドを含むクラスへのリンクは次のとおりです: RangeExtensions.cs。
メソッドはメソッドですSlice
。ページを検索してください。問題の型である Range は、基本的にある値から別の値への範囲であるため、上記のアルゴリズムに加えて、データの構築と保守が少し必要です。