AtCoderをやって17

問題

atcoder.jp

模範回答

累積和の問題だったのですが全く分からず、、、

色々なやり方があったのですが、これがとりあえずシンプルでわかりやすかった

累積和勉強します

N = gets.chomp.to_i
ws = gets.split(' ').map(&:to_i)

answer = []

N.times do |i|
  a = ws[0..i].sum
  b = ws[i+1...].sum
  answer << (a-b).abs
end

puts answer.min

AtCoderをやって16

問題

空港 A, B, C があり、それぞれの空港の間では、双方向に飛行機が運航しています。

空港 A, B 間の飛行時間は片道 P 時間、空港 B, C 間の飛行時間は片道 Q 時間、空港 C, A 間の飛行時間は片道 R 時間です。

いずれかの空港からスタートして他の空港に飛行機で移動し、さらにそのどちらでもない空港に飛行機で移動するような経路を考えます。

飛行時間の和は最短で何時間になるでしょうか。

atcoder.jp

自分の回答

p, q, r = gets.split.map(&:to_i)
a = p + q
b = p + r
c = q + r
if a <= b && a <= c
  puts a
elsif b <= a && b <= c
  puts b
else
  puts c
end

その他の回答

この回答は正直分からんかった。制約で飛行時間がP,Q<Rとかになっているのなら分かるのだが・・・

puts  gets.chomp.split(" ").map(&:to_i).sort[0..1].sum

(備忘録)AtCoderをやって15(Guidebook)

問題

atcoder.jp

自分の回答(他の方の回答参照しつつ)

まずsort_byの使い方で苦戦しました。さらに番号を要素にどう持たせて出力するかで悩みました。 空の配列を用意して、timesのブロックで渡した引数を配列に入れていけば良かったですね。 その後sort_by!で文字列、かつ点数の降順で並び替えを行いそれをeachの中でputsをしています。

N = gets.to_i
arr = []
N.times do |i|
  s, p = gets.split
  arr << [i+1, s, p.to_i]
end
arr.sort_by!{|i, s, p| [s, -p]}
arr.each do |a|
  puts a[0]
end

その他回答

最後のputsの部分をmapで書いている。これだともっと簡潔に書けるんですね。

n=gets.to_i
q=[]
n.times do |i|
  s,n=gets.split
  n=n.to_i
  q<<[s,-n,i+1]
end
puts q.sort.map{|a,b,c| c}

(備忘録)AtCoderをやって14

問題

atcoder.jp

他の回答

今回は問題の趣旨よく分からんかったので回答見ながら学習(とは言っても30パーセントくらいの理解)

累積和の理解が出来ず

n,m = gets.split.map(&:to_i)
x = 1
y = n
m.times do 
  l,r =gets.split.map(&:to_i)
  x = [x,l].max
  y = [y,r].min
end
if x <= y
  puts y-x+1
else
  puts 0
end
n, m = gets.split.map(&:to_i)
g = []

m.times { g << gets.split.map(&:to_i) }

min = 0
max = n
g.each do |l,r|
  min = [min, l].max
  max = [max, r].min
end

puts max - min < 0 ? 0 : max - min + 1

(備忘録)AtCoderをやって13

問題1

A 歳の高橋君が観覧車に乗ろうとしています。

この観覧車は、13 歳以上が乗るには B 円 (B は偶数) かかりますが、6 歳以上 12 歳以下の人はその半額で乗ることができ、 さらに 5 歳以下の人は無料で乗ることができます。

高橋君が観覧車に乗るには何円かかるかを求めてください。

atcoder.jp

自分の回答

age, fee = gets.split.map(&:to_i)
if age <= 5
  puts 0
elsif age <= 12
  puts fee / 2
else 
  puts fee
end

その他の回答

三項演算子の中に三項演算子を入れるパターンは思い付かなかった (ただ実務ではこれ見やすいのかな?という疑問は残る)

a,b = gets.chomp.split(" ").map(&:to_i)
puts a <= 5 ? 0 : (a <= 12 ? b/2 : b)

問題2

下記参照

atcoder.jp

自分の回答

a, b, c = gets.split.map(&:to_i)
cnt = 0
while cnt < 10
  d = a * c - b
  puts d
  c = d
  cnt += 1
end

その他回答

putsした後にわざわざ代入しなくても出た値をそのまま次の処理に入れればいい訳ですね。

r,d,x = gets.split.map(&:to_i)

10.times do
  x = r * x - d
  puts x
end

(備忘録)AtCoderをやって12(Dice and Coin)

問題

下記参照

atcoder.jp

自分の回答(不正解)

N, K = gets.chomp.split.map(&:to_i)
arr = []
i = N + 1
if N <= K
  # 分からなかった
else
  (1..N).each do |n|
  if n == 1
    probability = Rational(1, N) * Rational(1, 2)**(i)
    arr << probability
  else
    probability = Rational(1, N) * Rational(1, 2)**(i)
    arr << probability
  end
  i -= 1
  end
end
result = arr.sum
puts result.numerator / result.denominator

模範回答

tmpはサイコロの目の数。1からn面までのサイコロの目を検証。

n,k = gets.split.map(&:to_i)
ary = []
1.upto(n) do |i|
  tmp = i
  cnt = 0
  while tmp < k do
    tmp *= 2
    cnt += 1
  end
  ary << 1/(n.to_f) * 1/(2.to_f**cnt)
end
puts ary.sum

(備忘録)AtCoderをやって11

問題

A, B, C からなる長さ N の文字列 S と、1 以上 N 以下の整数 K が与えられます。 文字列 S の K 文字目を小文字に書き換え、新しくできた S を出力してください。

atcoder.jp

自分の回答

絶対にもっといい回答あると思ったけど思い付かなかった

n, k = gets.split.map(&:to_i)
s = gets.chomp.to_s
a = s.slice!(k-1)
puts s.insert(k-1, a.downcase)

その他の回答

単純にs[k-1]で指定箇所の文字取ってこれるからそれでいい訳ですね

n,k = gets.split.map &:to_i
s = gets.chomp
s[k-1] = s[k-1].downcase
puts s

問題

下記参照

atcoder.jp

自分の回答

無理やり通したけどめっちゃ汚いコード・・・

a = gets.chomp
b = a.slice!(2..3).to_i
a = a.to_i

if 1 <= a && a <= 12 && 1 <= b && b <= 12
  puts "AMBIGUOUS"
elsif 1 <= b && b <= 12
  puts "YYMM"
elsif 1 <= a && a <= 12
  puts "MMYY"
else
  puts "NA"
end

その他の回答

意外と愚直にやる方法しかなさそう?大きな変更はないですが、条件の部分を変数に代入して少し見やすくしたパターン

a = gets.chomp
b = a.slice!(2..3).to_i
a = a.to_i
x = 1 <= a && a <= 12
y = 1 <= b && b <= 12

if x && y
  puts "AMBIGUOUS"
elsif y
  puts "YYMM"
elsif x
  puts "MMYY"
else
  puts "NA"
end