座標圧縮について勉強した java
調べてもあまり引っかからなかったのでまとめておきます。
座標圧縮とは与えられる範囲は大きいが、全ての値を把握する必要はない場合(たとえば#で分けられた領域の数を数える問題など)に使えるテクニックです。
・・・・・・・・・・・・・#・・
################
・・・・・・・・・###・・・・
・・・・・・・・・###・・・・
################
・・・・・#・・・###・・・・
・・・・###・・###・・・・
上に座標圧縮を使うと
・・・・・・・#・
#########
・・・・・#・・・
#########
・・#・・#・・・
・###・#・・・
のようになります。領域を潰さずにサイズを小さくできましたね。
大まかな手順
まず、x軸について圧縮します。
・・・・・・・・#・
#########・
#########・
・#・・・・・・#・
0123456789
このような場合横に#が続いているところをカットしたいのですが
それを実現するために、左側に#の境界があるxをメモします
上の場合01289です
そして、セットに入っていない座標は無視して、01289の座標だけつなげます
こんな感じで。y軸についても同じことをして
圧縮できた
具体的な手順
01289を繋げて~とかいうのを具体的にどうやるか説明します。
壁(#)のある位置は複数の長方形で渡されており、左端の座標はx1に、右端の座標(半開区間)はx2の配列に格納されているものとします
この場合x1には{0,1,8} x2には{9,2,9}という風に入っています。
つまり0~9 ,1~2 ,8~9の3つが塗られている。
ここで、間の座標をカットするという事は使う数を小さい順に並べた01289で、8を3に,9を4にずらして、0からの順列にすることに他なりません。
つまり
x1{0,1,8} を {0 ,1 ,3}に
x2{9,2,9} を {4, 2 ,4}にしてやればx座標について圧縮した事になります(yも似た感じで)
・・・#・
####・
####・
・#・#・
数をずらすにはTreeSetに0と右端、x1,x2の値をすべて入れて、前から何番目にあるかを調べれば良いです
参考問題