この問題を解くための単純な方法はいわゆる「
ふるい」(sieve) という手法である.入力された部屋の面積の最大値を S
max とする.
まず,1 から S
max までの整数が部屋の面積としてありえるかどうかを示す配列 ExistXY[1..S
max] を {0, …, 0} に初期化する.ただし,0 はありえないことを示す.
x, y を適当な範囲で変化させて ExistXY[2xy + x + y] = 1 という代入を実行する.ただし,1 はその面積の部屋がありえることを示す.この操作の終了後も ExistXY[S] が 0 となっている場合,面積 S の部屋はありえない.x≦y と仮定しても一般性を失わないことに注意して,このアルゴリズムをまとめると以下のようになる.
ふるいのアルゴリズム
- begin
- for S = 1 to Smax do
- begin
- ExistXY[S] = 0 ;
- end ;
- x = 1 ;
- while 2(x2+x)≦Smax do
- begin
- y = x ;
- while (2xy + x + y)≦Smax do
- begin
- ExistXY[2xy + x + y] = 1 ;
- y = y + 1 ;
- end ;
- x = x + 1 ;
- end ;
- Exist[S] = 0 の面積 S を出力する ;
- end
ふるいの方法は S
max が小さいときには有効なのだが,この問題のように S
max が大きくなると配列 ExistXY が定義できない.あるいは定義できても大きすぎて実行時間が長くなるので有効ではない.
S = 2xy + x + y のとき S - x = 2xy + y = (2x + 1)y だから (S - x)
mod (2x + 1) = 0
が成り立つ.ただし,a
mod b は a を b で割ったときの余りを表す.よって,S が部屋の面積としてありえるかどうかかの判定のアルゴリズムは以下のようになる.
面積の判定アルゴリズム
- begin
- x = 1 ;
- while 2(x2 + x)≦ Smax do
- begin
- if ( (S - x) mod (2x + 1) ) = 0 then 「ありえる」と判定する ;
- end ;
- 「ありえない」と判定する ;
- end