C - Counting Squares Editorial by kyopro_friends


2点を決めたとき、「頂点を右回りに見たときその2点が連続するような正方形」は一意に決まります。そこで2点を全探索することを考えます。

しかしそのままだと、例えば上図の \(A,B\) の2点を選んだときと、\(B,C\) の2点を選んだときで同じ正方形を数えてしまいます。そこで、正方形の「右斜下向きの辺」に注目します。これは、真横を含まず真下を含むことにすればどのような正方形にもちょうど \(1\) つ存在します。

したがって、2点を選ぶとき、2点目を「最初に選んだ点から見て右下の位置にある点」だけから選ぶことで、過不足なく正方形を数えることができます。

2点を決めたとき、残りの2点の座標は下図を参考にうまく求める必要があります。

実装例(Python)

import itertools
S=[input() for _ in range(9)]
ans=0

for i1,j1,i2,j2 in itertools.product(range(9),repeat=4):
  # (i1,j1)から→↓の向きに(i2,j2)がある
  if i2>i1 and j2>=j1 and S[i1][j1]=="#" and S[i2][j2]=="#":
    di=i2-i1
    dj=j2-j1
    i3=i2+dj
    j3=j2-di
    i4=i3-di
    j4=j3-dj
    if 0<=i3<9 and 0<=j3<9 and 0<=i4<9 and 0<=j4<9 and S[i3][j3]=="#" and S[i4][j4]=="#":
      ans+=1
print(ans)

posted:
last update: