天下一プログラマー
天下一プログラマーコンテストが開催されている。どれどれ、ちょっと参加してみようかな。って、応募資格は学生さんのみ。残念。
予選第一回の問題が http://lab.klab.org/young/2009/07/%E5%A4%A9%E4%B8%8B%E4%B8%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E2009-web%E4%BA%88%E9%81%B8%E7%AC%AC1%E5%9B%9E%E6%A6%82%E6%B3%81/ に掲載されていたので、外野ながら挑戦してみた。言語は Ruby を選択。
第1問
- グレゴリオ暦では1年の平均日数は365.2425日というのを用いて、2001年から3000年までの日数を求める。
- 日曜日は2001年1月1日から数えて7日目なので、1 で求めた日数そのままを7で割る。
year = (3000 - 2001) + 1 day = (year * 365.2425).to_i puts day / 7
第2問
どうやって4文字の文字列を抽出するかが問題で、その他は特に問題ないと思う。ここでは、String#[first..last] で実装した。
str = "87104101110321051103211610410132991111171141151013211110232104117109971103210111810111011611544321051163298101991111091011153211010199101115115971141213210211111432111110101321121011111121081013211611132100105115115111108118101321161041013211211110810511610599971083298971101001153211910410599104321049711810132991111101101019911610110032116104101109321191051161043297110111116104101114443297110100321161113297115115117109101329710911111010332116104101321121111191011141153211110232116104101321019711411610444321161041013211510111297114971161013297110100321011131179710832115116971161051111103211611132119104105991043211610410132108971191153278971161171141013297110100327897116117114101115327111110032101110116105116108101321161041011094432973210010199101110116321141011151121019911632116111321161041013211111210511010511111011532111102321099711010710511010032114101113117105114101115321161049711632116104101121321151041111171081003210010199108971141013211610410132999711711510111532119104105991043210510911210110832116104101109321161113211610410132115101112971149711610511111046" i = 0 x = 0 while i + 3 < str.size num = str[i..(i + 3)].to_i if num % 3 == 0 x += 1 end i += 1 end puts x
第3問
この問題は解けなかった。いや、一応下に書いたコードで解けてるとは思うんだけど、計算量がものすごいので使い物にならない。問題を解く場合には、定石みたいなものがあると思うんだけど、わからなかったってことは勉強不足ってこと。うむ。
man = 10000 money = [10000, 5000, 2000, 1000, 500, 100, 50, 10, 5, 1] # お金 max = money.map { |m| man / m + 1 } # 最大何枚使用できるか c = 0 # 10,000円 max[0].times { |y1| sum1 = y1 * money[0] if sum1 == man c += 1 break end # 5,000円 max[1].times { |y2| sum2 = sum1 + y2 * money[1] if sum2 == man c += 1 break end # 2,000円 max[2].times { |y3| sum3 = sum2 + y3 * money[2] if sum3 == man c += 1 break end # 1,000円 max[3].times { |y4| sum4 = sum3 + y4 * money[3] if sum4 == man c += 1 break end # 500円 max[4].times { |y5| sum5 = sum4 + y5 * money[4] if sum5 == man c += 1 break end # 100円 max[5].times { |y6| sum6 = sum5 + y6 * money[5] if sum6 == man c += 1 break end # 50円 max[6].times { |y7| sum7 = sum6 + y7 * money[6] if sum7 == man c += 1 break end # 10円 max[7].times { |y8| sum8 = sum7 + y8 * money[7] if sum8 == man c += 1 break end # 5円 max[8].times { |y9| sum9 = sum8 + y9 * money[8] if sum9 == man c += 1 break end # 1円 max[9].times { |y10| if sum9 + y10 * money[9] == man c += 1 break end } } } } } } } } } } puts c