小池イーサンだお(^O^)/

読んでーーーー

AtCoder Beginner Contest 047を解いたよーーーー(^O^)/

AtCoder Beginner Contest 047

AtCoder Beginner Contest 047 - AtCoder Beginner Contest 047 | AtCoder

AとBだけ解けて
CとDは解けませんでした。
ガーーーン。
がんばっておべんきょうしなきゃ( ;∀;)

A問題

A: キャンディーと2人の子供 / Fighting over Candies - AtCoder Beginner Contest 047 | AtCoder

競プロ幼稚園に通う 2 人の子供がキャンディーの取り合いをしています。

3 個のキャンディーパックがあり、それぞれのパックにはキャンディーが a, b, c 個入っています。

えび先生はこの 3 個のパックを、キャンディーの個数が等しくなるように 2 人に分けようとしています。そのような分け方が可能かどうかを判定してください。

ただし、キャンディーをパックから取り出すことはできず、それぞれのパックをそのままどちらかの子供にあげる必要があります。

3個だけなのでそのまま書いてしまいました。

a, b, c = gets.split.map(&:to_i)
if (a+b==c)or(b+c==a)or(c+a==b)
	puts "Yes"
else
	puts "No"
end
少し改善

入力をソートすれば条件部分がすっきりしてよかった。

data = gets.split.map(&:to_i)
data.sort!
if (data[0] + data[1] == data[2])
	puts "Yes"
else
	puts "No"
end

B問題

B: すぬけ君の塗り絵 2 イージー / Snuke's Coloring 2 (ABC Edit) - AtCoder Beginner Contest 047 | AtCoder

xy 平面上に、左下の座標が (0,0)、右上の座標が (W,H) で、各辺が x 軸か y 軸に平行な長方形があります。最初、長方形の内部は白く塗られています。
すぬけ君はこの長方形の中に N 個の点を打ちました。i 個目 (1≦i≦N) 点の座標は (xi,yi) でした。
また、すぬけ君は長さ N の数列 a を決めて、各 1≦i≦N に対し、
ai=1 のときは長方形の x<xi をみたす領域
ai=2 のときは長方形の x>xi をみたす領域
ai=3 のときは長方形の y<yi をみたす領域
ai=4 のときは長方形の y>yi をみたす領域
を黒く塗りました。
塗りつぶしが終わったあとの長方形内での白い部分の面積を求めてください。

x,yの最大値最小値を範囲が狭まる方向に更新していけばいいだけ。

で、入力を配列に入れていこうと
以下のように書いたもののエラーになってしまい
無限に時間を溶かしてしまった。

x, y, a = Array.new(N)
for i in (1..N)
 	x[i], y[i], a[i] = gets.split.map(&:to_i)
end

prog.rb:4:in `block in

': undefined method `[]=' for nil:NilClass (NoMethodError)
from prog.rb:3:in `each'
from prog.rb:3:in `
'

結局、逐一最大値最小値を更新していくだけだから配列に保持する必要はないので単に変数で
受け取ればよかった。
もしくは行を一つの配列として受け取ればよかった。
最初のやり方に固執してしまうのは良くない。

面積が負の時0を返すようにしてしまった。
負*負=正となることに考えが至らなかった。
良くない。

W, H, N = gets.split.map(&:to_i)
 
x_max = W
x_min = 0
y_max = H
y_min = 0
 
N.times do
	x, y, a = gets.split.map(&:to_i)
	case a
	when 1
		if (x_min < x)
			x_min = x
		end
	when 2
		if (x_max > x)
			x_max = x
		end
	when 3
		if (y_min < y)
			y_min = y
		end
	when 4
		if (y_max > y)
			y_max = y
		end
	end
end
 
area = (x_max - x_min)*(y_max - y_min)
 
if (x_max - x_min) <= 0 or (y_max - y_min) <= 0
	puts 0
else
	puts area
end
少し改善

条件の不等号の向きも間違ったのでmax,min使ったほうが良かった。

W, H, N = gets.split.map(&:to_i)
 
x_max = W
x_min = 0
y_max = H
y_min = 0
 
N.times do
	x, y, a = gets.split.map(&:to_i)
	case a
	when 1
		x_min = [x_min,x].max
	when 2
		x_max = [x_max,x].min
	when 3
		y_min = [y_min,y].max
	when 4
		y_max = [y_max,y].min
	end
end
 
area = (x_max - x_min)*(y_max - y_min)
 
if (x_max - x_min) <= 0 or (y_max - y_min) <= 0
	puts 0
else
	puts area
end

==================== 解けたのはここまで ====================

C問題

C: 一次元リバーシ / 1D Reversi - AtCoder Beginner Contest 047 | AtCoder

きつねの次郎と三郎が一次元リバーシで遊んでいます。一次元リバーシでは、盤面には白か黒の石が一列に並んだ状態となっており、列の右端か左端に新たに石を打っていきます。通常のリバーシと同じように、たとえば白の石を打つことで黒の石を挟むと、挟まれた黒の石は白い石に変わります。

ゲームの途中で三郎に急用ができて帰ってしまうことになりました。このとき、盤面の状態は文字列 S で表されます。石は |S| (文字列の長さ) 個並んでおり、左から i (1≦i≦|S|) 個目の石の色は、S の i 文字目が B のとき黒、W のとき白です。

次郎は現在の盤面に対して、できるだけ少ない個数の石を新たに打つことで全ての石を同じ色にしようと考えました。最小で何個の石を打てばよいかを求めてください。

B=>W, W=>Bの境目の数を求めればよさそうだ。

とりあえずひと文字ずつ配列にして、
同じ文字が連続している場合はひとつの要素にして、
配列.lemgth-1で終わりだろう。

、、、と思ってメソッドを書いていたらうまくいかなくて放り投げてしまいました。

▼squeezeメソッド使えばやりたいことが出来たみたいです(squeeze, squeeze! (String) - Rubyリファレンス)

squeezeメソッドは、文字列中で同じ文字が連続している部分を1つの文字にまとめ、新しい文字列を返します。

s = gets.chomp
puts s.squeeze.length-1

メソッド知ってたら一瞬すぎる。

D問題

D: 高橋君と見えざる手 / An Invisible Hand - AtCoder Beginner Contest 047 | AtCoder

N 個の町が一直線上に並んでいます。行商人の高橋君は町 1 から出発し、リンゴの売買をしながら町 N へと向かいます。

はじめ高橋君は町 1 におり、リンゴを 1 つも持っていません。高橋君は次のいずれかの行動を繰り返し行います。

移動: 町 i (i<N) にいるとき、町 i+1 へ移動する。
リンゴの売買: リンゴを好きな個数だけ売買する。ここで、町 i (1≦i≦N) ではリンゴの買値も売値もともに Ai 円とする。ここで Ai は相異なる整数です。
1 つの町で売買するリンゴの個数に制限はありませんが、旅の中で売買するリンゴの個数は合計で (買う個数と売る個数を合わせて) T 個以下にしなくてはなりません。

高橋君は旅の利益、すなわちリンゴを売った代金から買った代金を引いた値を最大にするように旅をするとします。旅が終わったときに持っていたリンゴの価値は考えず、旅の中で売買した金額だけを考えます。

この旅に先立って、青木君は任意の町 i に対して Ai を好きな非負整数 Ai' に変えるという操作を好きなだけ行うことができます。ただし、この操作は行うごとに |Ai−Ai'| のコストがかかります。操作後には異なる町の間でリンゴの値段が同じになっていても構いません。

青木君の目的はできるだけ少ない合計コストの操作で高橋君の利益を少なくとも 1 円下げることです。合計コストの最小値を求めてください。

ただし、元の状態で高橋君が 1 円以上の利益を上げられることは仮定して構いません。

わからないので時間をかけてじっくり考えます( ;∀;)