AtCoder参加したったー （ABC158編）

こんにちは！バイオインフォマティクス系オタク修士学生のroadricefieldです！実は趣味でAtCoderに参加していたのですが今回から時間があれば自分の復習のために記録を残していこうと思います！　　
今回は2020年3月7日に開催されたABC158に参加したときの記録です. まだまだ勉強不足でD問題までしかACできませんでしたが今後EまではACできるように頑張りたいと思います！ 普段はC++も使うのですが今回はすべてPythonで間に合いそうだったのですべてPythonで解きました！

# [A問題](https://atcoder.jp/contests/abc158/tasks/abc158_a)

これ, 最初問題文の意図がつかめなくていきなり「は？」ってなってしまったんですがよく考えたら与えられる文字列 *S* が同一の文字のみでできているかどうかを判定すればよいだけです.  

私の解答

```python
S = input()
if S[0] == S[1] and S[1] == S[2] and S[0] == S[2]: print("No")
else: print("Yes")
```  

# [B問題](https://atcoder.jp/contests/abc158/tasks/abc158_b)  

結局は高橋くんが周期的に *A* 個の青いボールと *B* 個の赤いボールを置いていくだけなので前から *N* 個までに *(A + B)* 個のセットが何個あるかを割り算で求めてその商 × *A* をまず求めます. あとはあまりが *A* より大きいときはそれに *A* を足し, あまりが *A* より小さいときはあまり自体を足したものが答えとなります.  

私の解答

```python
N, A, B = map(int, input().split())
 
div = int(N/(A+B))
 
amari = N%(A+B)
 
if amari > A:
    print(A*div + A)
else:
    print(A*div + amari)
```  

# [C問題](https://atcoder.jp/contests/abc158/tasks/abc158_c)  

これもすぐには方針が思いつかなくて焦りましたが落ち着いて考えるとまず, 8 %消費税率で消費税が *A* 円になる最小の税抜価格は ceil(*A*/0.08) = ceil(12.5 *A*) 円です. 10 %消費税率で消費税が *B* 円になる最小の税抜価格は ceil(*B*/0.1) = ceil(10 *B*) 円です. これらのうち小さい方を *N* とします. 例えば8 %消費税率で消費税が *A* 円になる最小の税抜価格, ceil(12.5 *A*) 円のほうが小さかったものとします. *N* = ceil(12.5 *A*) とし, *N* に1を足していって最初に floor(0.1 *N*) = *B* となったときの *N* が答えです. *N* に1を足していっている途中で floor(0.08 *N*) が *A* より大きくなってしまう場合があるのでそのときは答えが存在しないので-1を出力します. 大小関係が反対の場合も同様です. Pythonではint()で囲えばそれがfloorになります.  
ってややこしいな！！！あとMarkdownでceilやfloorの記号どうやって書くんですか... 誰か教えて下さい！
  
私の解答  

```python  
import math
A, B = map(int, input().split())
ans = -1
 
flg = True
 
if math.ceil(12.5*A) >= B*10:
    N = B*10
    while int(N*0.08) < A:
        N += 1
        if int(N*0.1) > B:
            flg = False
            break
    if flg: ans = N
 
else:
    N = math.ceil(12.5*A)
    while int(N*0.1) < B:
        N += 1
        if int(N*0.08) > A:
            flg = False
            break
    if flg: ans = N
 
print(ans)
```  

# [D問題](https://atcoder.jp/contests/abc158/tasks/abc158_d)  

これは問題文の操作をそのまま実装しては文字の反転や頭に文字を追加するときに処理に時間がかかってテストケースによっては2秒以内に答えを出力できません. （たしかPythonでは頭に文字を追加するときは文字列を保持する配列の添字を一つずつ後ろにずらす操作がされてしまったはず. だから遅いはずです.）なのでここは今文字列が反転しているかどうかを保持しながら元の向きで見たときの *S* の頭についていく文字としっぽについていく文字を別々のリストに**append**していき（ここ重要！appendによる追加はリストの末尾に足すだけなので処理時間が短い.）最後に向きに注意してつなげて出力するという作戦でいきました.  

私の解答  

```python

S = input()
Q = int(input())
 
flg = "moto"
 
atama = list()
shippo = list()
 
for _ in range(Q):
    tmp = list(map(str, input().split()))
    if flg == "moto":
        if int(tmp[0]) == 1:
            flg = "hanten"
        else:
            if int(tmp[1]) == 1:
                atama.append(tmp[2])
            else:
                shippo.append(tmp[2])
    
    else:
        if int(tmp[0]) == 1:
            flg = "moto"
        else:
            if int(tmp[1]) == 1:
                shippo.append(tmp[2])
            else:
                atama.append(tmp[2])
 
if flg == "moto":
    atama = atama[::-1]
    print("".join(atama) + S + "".join(shippo))
 
else:
    shippo = shippo[::-1]
    print("".join(shippo) + S[::-1] + "".join(atama))
```  

# 感想

私が解けたのはここまでです. これからはDPなどの基本的なアルゴリズムを習得してE問題までACすることを目指します！生物科学専攻にしては頑張ったほうだと思います.