AtCoder Beginner Contest 258 メモ(A-D)
今回の結果
2AC
B問題でDifficulty500超え、しかもC問題よりも高い。
ここに結構時間を費やしてしまってC問題までACできなかった。
D問題までは時間があれば解ける問題だったので、時間内に解けるようになるというのが今の自分の課題。
A - When?
Difficulty: 10
問題文
AtCoder Beginner Contest は通常、日本標準時で
HH:MM
の形式で出力してください。ただし、HH
は MM
は分を表します。時間または分が
制約
-
はK 以上0 以下の整数100
入力
入力は以下の形式で標準入力から与えられる。
出力
入出力例
入力例 1
63
出力例 1
22:03
※ 10:03 や 22:3 は不正解となる
入力例 2
45
出力例 2
21:45
入力例 3
100
出力例 3
22:40
参加中に考えたこと
以下の2点の処理を行えばよい。
-
HH
は60未満なら21
、60以上なら22
になる -
MM
が一桁になる場合には先頭に0
をつける
2つ目はMMの値を見て0埋めする方法でやっちゃったけどprintf使うのが楽かな。
B - Number Box
Difficulty: 511
問題文
正整数
このマス目は上下および左右がつながっているものとします。つまり以下が全て成り立ちます。
高橋君は、上下左右および斜めの
高橋君は
制約
1≤N≤10 1≤A_{i,j}≤9 - 入力はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
答えを出力せよ。
入出力例
入力例 1
4
1161
1119
7111
1811
出力例 1
9786
入力例 2
10
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
1111111111
出力例 2
1111111111
参加中に考えたこと
全探索。
各マス目について8方向の値を取っていくので、各方向について処理を書くのは面倒だしバグを生みやすい。
8方向を順に見ていくための座標の移動については、以下のような配列を持っておくと短い3重ループでコードが書けた。
(ここに辿り着くのに時間がかかり過ぎた)
const int dx[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};
上下左右が繋がっている部分はmodを使ってやればよい。
C++の場合、マイナスの値に対してmodを取ると期待する値とは異なる値になってしまうので、先に+Nしておいてからmodを取るようにする。
あと、出力例2に「答えが32bit型整数値に収まるとは限らない」と書かれているが、一番大きい値を取りたい、かつ桁数は揃っているので、数値で比較するのではなくて文字列として扱えばよさそう。
何回かWA出してしまったが、なんとかACできた。
考察・感想
配列を持っていればあっという間に解ける問題だったかな。
座標を扱う問題ではたまに出るので、4方向と8方向の2種類の配列を持っておくのがいい。
C - Rotation
Difficulty: 419
問題文
正整数
以下で説明されるクエリを
-
1 x
: 「 の末尾の文字を削除し、先頭に挿入する」という操作をS 回連続で行う。x -
2 x
: のS 番目の文字を出力する。x
制約
2≤N≤5×10^5 1≤Q≤5×10^5 1≤x≤N ∣S∣=N -
は英小文字からなる。S -
2 x
の形式のクエリが 個以上与えられる。1 -
はすべて整数。N,Q,x
入力
入力は以下の形式で標準入力から与えられる。
それぞれのクエリは以下の形式で与えられる。ここで、
出力
2 x
の形式の各クエリについて、答えを一行に出力せよ。
入出力例
入力例 1
3 3
abc
2 2
1 1
2 2
出力例 1
b
a
入力例 2
10 8
dsuccxulnl
2 4
2 7
1 2
2 7
1 1
1 2
1 3
2 5
出力例 2
c
u
c
u
参加中に考えたこと
クエリ2は
制約の値が大体は
dequeとか使ったら時間早くなるかなということを考えて試したところでタイムアップ。
考察・感想
1日置いて考え直した。
クエリ2は文字列を出力するだけで要素の変更はない。クエリ1はSの順番が変わるだけで要素数自体は変わらない。
クエリ1の処理で実際に文字を入れ替えるのではなく、動かしたとみなす工夫をすればよいことに気づいた。動かした後に元々の文字列が何文字動いたかの位置の情報だけもっておけば、そこからクエリ2で出力したい文字も計算で求められる。
ここの計算に苦戦したが、自分の場合は「クエリ1を行った後の文字列の先頭が元々の何文字目か?」を持っておくと考えて解くことができた。
解説を見るとクエリ1を行った回数を持つと書かれていて、そのほうがシンプルに考えられたかな。
D - Trophy
Difficulty: 687
問題文
初めて
初めから遊べるのは
合計
制約
1≤N≤2×10^5 1≤A_i,B_i≤10^9 (1≤i≤N) 1≤X≤10^9 - 入力は全て整数
入力
入力は以下の形式で標準入力から与えられる。
出力
答えを出力せよ。
入出力例
入力例 1
3 4
3 4
2 3
4 2
出力例 1
18
入力例 2
10 1000000000
3 3
1 6
4 7
1 8
5 7
9 9
2 4
6 4
5 1
3 1
出力例 2
1000000076
考察・感想
問題文をぱっと見た感じ、そんなに難しい問題ではなさそうに思えた。
ストーリー映像とゲームプレイの2段階あるところが一見複雑にはみえるけども、最小時間になるケースって、2回以上クリアするステージは1つしかないのでは?というのが明らかな気がする。
ステージkまで進む場合の必要な時間は、ステージ1~kまでのストーリー映像とゲームプレイの時間の合計+(X-k-1)回ゲームプレイをする時間になる。数式であらわすと、
になる。
ステージ1から順番にループしてこの最小値を求めればOK。
ACするまでC問題よりも時間はかからなかった。
解いていて詰まりそうになった点としては2つあった。
1点目は、ループの終了条件として
5 3
6 12
3 9
4 3
1 2
1 10
2点目は最小値をして持っておく変数の初期値。
今まで大きな値であればいいかと思いあまり意識せず1e18
として桁数だけ合わせていたが、これだといくつかのテストケースでWAしてしまう。この問題の場合の答えの最大値としては、
いろんな人の提出ソースを見てみると、定数を用意している人は多いがその値はというと 2e18+7
、 9e18
、1<<62
、 9223372036854775807
などのようにバラバラ。用意されている定数を使うのが一番無難だろうか。公式解説では numeric_limits を使っているが書き方がやや長いので LLONG_MAX
でいいかと思った。
Discussion