A - Programming Education
入力:
または
制約:
は1または2
出力: のとき、'Hello World'と出力し、のとき、を出力する。
今回は珍しいことに処理の分岐をする必要がありました。
N = readln.chomp.to!int; if(N == 1) { writeln("Hello World"); } else { auto A = readln.chomp.to!int, B = readln.chomp.to!int; writeln(A + B); }
感想: やるだけです。問題文がヤバいなあって感じ。
B - Time Limit Exceeded
入力:
出力: コストが最小となる経路のコストを出力
制約:
まず、以内に帰宅できない経路については弾きます。この条件を満たすコストの中での最小値を出力すればよいです。
int[] times; foreach(i; 0..N) { /* 入力を読み込む。 */ if(t <= T) times ~= c; } if(times.length != 0) writeln(times.reduce!min); else writeln("TLE");
感想: 'TLE'のときのケースについて処理するのを忘れてしまうと
'WA'するので気をつけましょう。
C - Pyramid
入力:
出力:
制約:
はちょうど1つに特定される
このような制約や条件が複雑な問題は、全探索をすることを考えます。
具体的には、今回はの3つの値について全探索すればよいです。
foreach(posY; 0..101) { foreach(posX; 0..101) { foreach(H; h.reduce!min..h.reduce!min+201) { bool flag = true; foreach(i; 0..N) { auto dist = max(0, H-abs(posX-x[i])-abs(posY-y[i])); if(dist != h[i]) { flag = false; break; } } if(flag) { writefln("%d %d %d", posX, posY, H); return; } } } }
感想: コンテスト中に解けなかった。「基本は全探索」この言葉を忘れてはいけない。あと、実行時間の制約も見ておくべきだと思った。
D - Partition
入力:
出力: の最大値
制約:
サンプルにない例を見てみましょう。
としてみます。この場合、出力は65になります。
195を素因数分解してみると、となります。
ここで注目したいのは、が出力になっていることです。
でははどこにいったのか、と考えてみると、実はの場合が考えられることから、それぞれを1つか2つずつ取っていることがわかります。
よって、「N以上でMを割りきれる最小の数」を探して、その値でMを割った値を出力すればいい、という方針が立ちます。なお、この値をとすると、探索すべきkの範囲はで十分です。
ただし、このやり方だと、テストケースにはないものの、一番計算に時間がかかるような「Nが2でMが以下の素数」などのパターンだと多分間に合わなくなってしまいます。
ジャッジ側が少しだけ情けを与えてくれたためにACすることができました。
int k = N; while(k <= M / 2) { auto r = M % k; if(r == 0) { writeln(M / k); return; } k++; } writeln(1);
感想: 割と単純明快なコードでACすることができました。
C問題より簡単に感じましたが、chokudaiさん曰く「それはAtCoderで遊んでいる層が数学に強い傾向にあるためであって、一般的にはC < Dという難易度になっているのは間違いないはず」とのことでした。
確かに全探索することを思いつけば簡単だったのかも…?
A: Submission #3341345 - AtCoder Beginner Contest 112
B: Submission #3342324 - AtCoder Beginner Contest 112
C: Submission #3357731 - AtCoder Beginner Contest 112
D: Submission #3348620 - AtCoder Beginner Contest 112