C - Counting Squares Editorial by AngrySadEight


公式解説より計算量は悪くなりますが,あまり難しいことを考えずに実装できる解法を紹介します.

まず,問題の制約より,ポーンが置かれているのは \(x\) 座標,\(y\) 座標が \(1\) 以上 \(9\) 以下の整数であるような座標に限られます.このような座標のうちの \(4\) 点を決め打つと正方形が一意に決まるので,\(4\) 点の組み合わせを全探索し,その \(4\) 点からなる正方形があるかどうかを判定すれば良いです.

\(4\) 点の座標が与えられたときにその \(4\) 点からなる正方形があるかどうかの判定方法には様々ありますが,比較的簡単に判定できる方法の一つは,\(2\) 点間の距離を用いた次のような判定方法です.

\(4\) 点のうちの \(2\) 点間を結ぶ \(6\) 本の線分について,その長さを小さい順に並べたものを, \(d_1, d_2, d_3, d_4, d_5, d_6\) とする.このとき,次が全て成り立っていれば,その \(4\) 点からなる正方形があるといえる.

  • \(d_1 = d_2 = d_3 = d_4\)
  • \(d_5 = d_6\)
  • \(d_5 = \sqrt{2}d_1\)

これは辺の長さを実際に全て求めることによって定数時間で判定可能です.なお,上の3つ目の条件を実際に判定する場合は,整数の範囲内で判定できるよう,上記の条件式の代わりに,両辺を二乗した \(d_5^2=2d_1^2\) を判定するとよいです.

計算量についてですが,頂点の候補数を \(N\) とすると,\(O(N^4)\) となります.\(N=81\) であるので,本問題の制約下において十分高速に動作します.

posted:
last update: