私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「ストレート・ラインズ」(CodeIQ)を参照してください。
2 以上の自然数 n に対し、n×n の格子状に並んだ点を考えます。
これらの点のうちちょうど 2 個の点を通る直線の数を F(n) と定義します。
例えば F(2)=6 です。題意を満たす直線は以下の 6 通りです。
また、F(3)=12 です。題意を満たす直線は以下の 12 通りです。
同様に、F(4)=48, F(5)=108, F(6)=248, F(7)=428, F(10)=1900 となることが確かめられます。
標準入力から、自然数 n (2 ≦ n ≦ 40)が与えられます。
標準出力に F(n) の値を出力するプログラムを書いてください。
Rubyで解答しています。
def f(n,k) ret = 0 for x in -n..n next if (k*x).abs >= n for y in -n..n next if (k*y).abs >= n # fomulaの(x,y)=1は最大公約数が1のことらしい next if x.gcd(y) != 1 ret += (n-(k*x).abs)*(n-(k*y).abs) end end return ret end def a018809(n) return (f(n,3) - 2*f(n,2) + f(n,1)) / 2 end # main while line = gets line.strip! next if line.empty? p a018809(line.to_i) end
★★★の問題です。
OEIS直行でした。
入力値を数値にしてa018809()に渡し、結果を印字します。
問題を解きます。
OEISで見つけたfomulaの通りです。
A018809のfomulaにあったf(n,k)を実装しただけです。
OEIS直行ですぐに見つけたのはよかったのですが、fomulaが読めない(苦笑)。
コードのコメントにもありますがfomulaにあった(x,y)=1がなんのことか分からない。関連のリンクか何かを見ていたらgcdという単語が出てきたので、調べたら最大公約数とあったので、x,yは互いに素かな? と思ってやって見たら上手くいったという結果です。