AtCoder Beginner Contest 158お疲れ様でした!
公式ページ
今回の自分の書いたコードはこちら
結果はA-DまでACできました。
以下簡単に解説します。
問題A
引数に文字長3の文字列が与えられて、それがAAA
かBBB
ならNo
と出力すればOKです。
問題B
N, A, Bが与えられて、N / (A+B)が大事になってくる問題。
Nこの列にA個の青いボールとB個の赤いボールを交互に並べていくので、このN/(A+B)が繰り返された回数となります。
(N/(A+B))*AをベースにN%(A+B)に青いボールが何個あるのかを足せばOKです。
問題C
消費税が8%なら税金がA円、10%なら税金がB円です。
ここで、以下に注目。
1 \leqq A \leqq B \leqq 100
もとの値段を1~1000円まで計算して、該当するものを出力すればOKです。
A円、B円からもとの値段を算出しようとすると大変です。
問題D
文字列を反転させたり、末尾や先頭に加えたりする問題です。
いちいち反転させていたら間に合わないな、と思ったので、反転フラグみたいなものを作って、実際に文字列を反転せずに、反転かどうかはそこで管理しました。
そして、末尾か先頭に文字を足す部分ですが、反転かどうかのフラグを見てどっちに足すか判断するようにしました。
これでTLEだったので、文字列の頭に文字を足すことが計算量が多いと推測しました。
なので、先頭に加えるべき文字列というのを別途管理することでACになりました。
具体的なコードでは、加えるときは以下のような感じで
int f = sc.nextInt();
if ((f == 1 && !isReverse) || (f == 2 && isReverse)) {
front.append(sc.next());
} else {
sb.append(sc.next());
}
出力するときはこんな感じ
if (isReverse) {
print(sb.reverse().toString() + front.toString());
} else {
print(front.reverse().toString() + sb.toString());
}
問題E
問題の方針は最後の最後で出たのですが、時間切れ。
3543を3で割る例で考えます。
3000/3500/3540を3で割った余りと、
3/43/543を3で割った余りと、
3543を3で割った余りがあれば、求める答えはでてきます。
今回は3543を3で割った余りが0です。
3000を3で割った余りも0なので、3/43/543の中から3で割った余りが0のものを見つけてくれば、それらを除いた部分文字列は3で割り切れます。
3000と3540を3で割った余りが0、3と543を3で割った余りが0なので2*2
3500を3で割った余りが2、43を3で割った余りが1なので、1*1
今回は3543が3で割り切れるので+1
で6と答えがでます。
3000を3で割った余りですが、3543を3で割った余りと、543を3で割った余りがあれば計算できます。
ので、計算すべきは3/43/543/3543と、末尾から1つずつ値を増やしていった余りを貯蔵しておけばよさそうです。
43を割った余りを保持していれば(5 mod 3) * (100 mod 3)で計算できます。
この桁数ぶんのmodも保持して計算しておきます。
なんかうまく言葉で言い表せないんですけど、これで解けると思います。。
問題F
手つかずです。笑
レーティングは計算中ですが下がっていそうです。。
(追記)
974→979と微妙に上がりました笑
E問題に手が届きそうっていうのがしばらく続いていたのですが、今回は少し遠かったなぁ・・・
今回のようにE問題がなかなかの難易度だと、A-D問題をいかに早く解くかで順位が多きく変わってきますね。。
基本的なfor文とか書くのに時間結構使っている気がするので、もうちょい効率化できるところはしていきたいと思います、、