SRM546 DIV2 -Level2

問題


①座標上にある2つの長方形の左下と右上の座標が与えられる。
②2つの長方形の重なりが四角形の時はrectangle、線で接している場合はsegment、
 点で接している場合はpoint、接していないときはnoneを返す。

解き方


単純に場合分けで解いてもよいが複雑になり間違えやすくなる&コードが書きにくくなるので、数学的に簡単にできないか検討する。

まず2次元の問題ということで、それぞれ1次元の問題に分割できないか検討する。
今回の場合はx軸とy軸はそれぞれ影響を与えないので独立に考えられる。

次に、x軸が線・点を作れるか、y軸も同じように線・点を作れるか
という考え方ができれば、x軸とy軸の組み合わせによってどの重なりになるか
求めることができる。

最後に各軸が線・点を作れる場合を考える。
1つ目の長方形の最左辺と最右辺がa、bとすると、
長方形の中にあるx軸の値はa<=x<=bとなる。
同様に2つ目の最左辺と最右辺をc、dとすると、
c<=x<=dとなる。

ここで2つの条件を合わせると、
max(a,c)<x<min(b,d)がxの範囲となる。

つまりxのとりうる範囲 min(b,d)-max(a,c)が
複数であれば線、
1点のみであれば点、
存在しなければ、どちらも作れないということがわかる。

これをy軸も同じように判定すれば簡単に求められる。

コード


class TwoRectangles {

public:

int f(int x){
if(x>0)return 1;
if(x==0)return 0;
return -1;
}

string describeIntersection(vector<int> A, vector<int> B) {

int checkx=f(min(A[2],B[2])-max(A[0],B[0]));
int checky=f(min(A[3],B[3])-max(A[1],B[1]));

if(checkx==1 && checky==1)return “rectangle”;
if(checkx==1 && checky==0 || checkx==0 && checky==1)return “segment”;
if(checkx==0 && checky==0)return “point”;
return “none”;

}

};

このエントリーをはてなブックマークに追加