【AtCoder:9回目】AtCoder Beginner Contest 132の振り返り(Ruby)

【目次】

【本題】

今回は 6/29(土)に開催されたAtCoder Beginner Contest 132の振り返りを行います。

AtCoder Beginner Contest 132 - AtCoder

今回は3問まで解けました。

めちゃくちゃトントン拍子で進んだので、もしや初の4問目も回答出来るのでは!?っと思ったのですが、全く検討が付かず・・・

ここ辺りになってくると、プログラミングというより、完全に数学の世界ですね・・・

レーティングは微増です。

A - Fifty-Fifty

問題文 長さ 4 の英大文字からなる文字列 S が与えられます。 S がちょうど 2 種類の文字からなり、かつ現れる各文字はちょうど 2 回ずつ現れているかどうかを判定してください。

制約 S の長さは 4 である S は英大文字からなる

これ問題読み違えてました・・・

「かつ現れる各文字はちょうど 2回ずつ現れているか」というところを、「2文字づつ」と勘違いしていました・・・

なので通りはしたものの、めっちゃ無駄なコードになってます・・・実装したコードがこちら。

s = gets.chomp.split("")

s_uniq = s.uniq

if s_uniq.size == 2 && s.count(s_uniq[0]) == 2 && s.count(s_uniq[1]) == 2
  puts 'Yes'
else
  puts 'No'
end

こっちで良かったです・・・

s = gets.chomp.split("")
 
puts s.uniq.size == 2 ? 'Yes' : 'No'

B - Ordinary Number

問題文 { 1 ,

2 ,

. . . ,

n } の順列 p = { p 1 ,

p 2 ,

. . . ,

p n } があります。

以下の条件を満たすような p i ( 1 < i < n ) がいくつあるかを出力してください。

p i − 1 ,

p i ,

p i + 1 の 3 つの数の中で、 p i が 2 番目に小さい。 制約 入力は全て整数である。 3 ≤ n ≤ 20 p は { 1 ,

2 ,

. . . ,

n } の順列である。

pを配列に入れたら、nで作った繰り返し処理の中で、順番に比較を行う方式で行きました。

なお、配列の両端は比較対象が揃わないので除外します。

そして注意点は、piが2番目に来れば良いので、pi−1とpi+1はどちらが大きくても構わないという事です。つまり両方のパターンの条件式が必要です。

そんなこんなで作ったコードがこちら。

n=gets.to_i
p=gets.split.map &:to_i
 
answer = 0
n.times do |i|
  next if i == 0 || i == n - 1
  answer += 1 if (p[i+1] > p[i] && p[i-1] < p[i]) || (p[i+1] < p[i] && p[i-1] > p[i])
end
 
puts answer

ちょい力技感がありますね・・・

そんな中、面白い実装方法を見つけました。

N = gets.to_i
P = gets.split.map &:to_i
p P.each_cons(3).count{|a|
  a[1] == a.sort[1]
}
puts answer

each_consというのは、引数で指定した数の要素を繰り返し配列から取り出して、ブロックを実行するメソッドです。

引数に3を指定して、sortメソッドで順番を変えたとしても、2番目の位置になるかをチェックする方法です。

こちらの方がスマートでかっこいいですね!

C - Divide the Problems

問題文 高橋君は、 N 個の競技プログラミング用の問題をつくりました。 それぞれの問題には 1 から N の番号がついており、問題 i の難易度は整数 d i で表されます(大きいほど難しいです)。

高橋君はある整数 K を決めることで、

難易度が K 以上ならば「 A R C 用の問題」 難易度が K 未満ならば「 A B C 用の問題」 という風に、これらの問題を二種類に分類しようとしています。

「 A R C 用の問題」と「 A B C 用の問題」が同じ数になるような整数 K の選び方は何通りあるでしょうか。

制約 2 ≦ N ≦ 10 5 N は偶数である。 1 ≦ d i ≦ 10 5 入力は全て整数である。

これは中央値(偶数なので二つ)を取得して、それらの差で区切る位置のパターンを求めました。

それがこちらです。

n=gets.to_i
d=gets.split.map &:to_i
 
d_sort = d.sort
p d_sort[d_sort.size/2] - d_sort[d_sort.size/2-1]

d_sort.sizenも同じ値なので、nを使った方が良かったですね。

またd.sort!にすれば、レシーバ自身を上書きしてくれるので、わざわざ変数に入れる必要もありませんでした。

n = gets.to_i
d=gets.split.map &:to_i
 
d.sort!
puts d[n / 2] - d[n / 2 - 1]