はじめての競技プログラミング
何を創るか考えるのって難しくて雑にプログラム書きたいってときに なかなかプログラミングするところまで行けないっていうことが僕の場合多々あります..
昔は,Paizaさんの問題といてなにこれ楽しーってなってたり, 最近では,インターン選考などでコーディングテストをやっていて, めっちゃ楽しい.
もともと,多分競技プログラミングが向いているたちなんだろうなと薄々感づいていまっしたが, なんとなーくやるタイミングをつかめず,,,
今日たまたま暇でなんかしたいなあと思っていたので, 初めて参加してきました.
参加してきたコンテストはこれ
結果から言うと, B問題で謎つまりをして惨敗 でも楽しいですね.
また,土日で9時ごろ空いているときにはじゃんじゃんチャレンジしていきたいなーというお気持ち
以下,しょうもなミスの反省
B問題は,50個の2次元平面上に配置されたボールをあるルール(問題見てもらうのが早い)で全て回収したときのコストの最小値を計算するもの
僕は,ただRubyが書きたかっただけってのもあったので, Rubyで挑戦しました.
最初は無難にpとqになる得る数字全網羅して,カウントして一番大きいのだしゃええやんと このコードを書きました...
N = gets.to_i
x, y = N.times.map{gets.split.map(&:to_i)}.transpose
hash = Hash.new
N.times do |i|
(i+1...N).each do |j|
new_x = x[i] - x[j]
new_y = y[i] - y[j]
hash["#{new_x},#{new_y}"] ||= 0
hash["#{new_x},#{new_y}"] += 1
end
end
puts N - hash.max{|x, y| x[1] <=> y[1]}[1]
ただこれだと,Nが1のときにエラー吐くのと, jをi+1~Nまででやっちゃってたのがだめだったぽいんですよねええ それに気づかず,
そもそも考え方が間違っているんじゃないかと 無駄に深く思考してしまいます...
そこで何を思ったか,コスト0のとり方をどれだけ連続でできるかを 考えないと行けないんだと,当時神がかったと思った僕の頭は判断しました.
その結果生まれたクソコードがこれ
def find_next(number, p, q, x, y, load, max)
max_load = Array.new
number.times do |n|
next if load.include?(n)
if((x[load.last] - p == x[n]) && (y[load.last] - q == y[n]))
load.push(n)
if max < load.length
max = load.length
max_load = load.dup
end
if max >= find_next(number, p, q, x, y, load, max)[0]
load.pop
end
end
end
return [max, max_load]
end
N = gets.to_i
x, y = N.times.map{gets.split.map(&:to_i)}.transpose
hash = Hash.new
N.times do |i|
N.times do |j|
next if i == j
new_x = x[i] - x[j]
new_y = y[i] - y[j]
hash["#{new_x} #{new_y}"] ||= 0
hash["#{new_x} #{new_y}"] += 1
end
end
hash.sort{|a, b| b[1] <=> a[1]}
max = 0
hash.each do |key, value|
p, q = key.split.map(&:to_i)
N.times do |i|
load = Array.new
load.push(i)
tmp_max = 0
tmp_max, tmp_load = find_next(N, p, q, x, y, load, tmp_max)
if max < tmp_max
max = tmp_max
end
end
end
if N == max
puts N - max + 1
else
puts N - max
end
find_nextでx,yにp, qっていう数字を与えた時,どの順番でボールを回収すれば,連続でコスト0が達成される最長になるか,計算するコードを作ります.
いつの間にか,jをi+1~Nまででやっちゃってたのを直してるし,,,
ここまで,コードを書いて無事2時間終了,,,2時間のうち1時間50分をこのどうやったら連続でコスト0が達成されるか見つけるコードを書き続けていました.
終わってから,他の方のコードを見ながら ACすることできたコードがこれ
N = gets.to_i
x, y = N.times.map{gets.split.map(&:to_i)}.transpose
hash = Hash.new
N.times do |i|
N.times do |j|
next if i == j
new_x = x[i] - x[j]
new_y = y[i] - y[j]
hash["#{new_x},#{new_y}"] ||= 0
hash["#{new_x},#{new_y}"] += 1
end
end
puts N - (hash.values.max || 0)
ほぼほぼ,最初の方にできてたコードで, 大半の時間を費やしたコードは消えてなくなりました...
振り返るとただただ馬鹿ですが, まあ,初めてでB問題がどれくらいの難易度かわからず 勘ぐり過ぎてしまったっていうの(とほろ酔い)が原因ですかね.
また,土日の9-11時が空いているときには, リベンジしたいですね.
結局,無駄でしたが,find_nextの関数を考えているとき, 最高に楽しかった...