masuTomo’s blog

競技プログラミングの勉強メモです.主にPythonを使用します.数学の記事も書くかもしれません.

yukicoder No.927 Second Permutation

時間ができたらyukicoderの★1.5~★2あたりを解いて勉強することにしている。今日はこれ。

No.927 Second Permutation

No.927 Second Permutation - yukicoder

問題を読んだら,やることはわかる。
というか短い桁数のものなら人間の手でやった方が楽ちん。 (競技プログラミングの最初につまづきそうなポイントとして,やりたいことはあるけど(わかってるけど)うまく実装できないということがあると思うが,この問題はまさにそんな感じ)

  1. 入力を取得(43581)

  2. 降順にソートする(85431)

  3. 末尾の数字から順番にチェックしてうまいこと数字を入れ替える(85413)

で,上記のうまいことの部分をちゃんと実装することが大切(例外処理とかもあるけど,まぁそれは置いておこう)。
一番小さい数字と2番目に小さい数字を入れ替えるということでよい。 ただし,一番小さい数字が複数個あった場合にも対応できるようにしておくこと。肝の部分は以下のような感じで書けばよい。

#X:入力で受け取った整数をlistにして格納
#cntMin:一番小さい数字の個数
X[-cntMin-1], X[-cntMin] = X[-cntMin], X[-cntMin-1]

ちなみに,pythonでは値Aと値Bの入れ替えが以下のように簡単に書ける。

A,B = B,A

また,listの一番後ろの要素から順番にアクセスするにはこんな感じ。

L = ["a","b","c"]
print(L[-1],L[-2])

#c b

コード全体はこのようにしてみた。

X = list(str(input()))
X = sorted(X, reverse=True)
setX = set(X)
if len(setX) <= 1 or len(X) - X.count("0") <= 1:
    print(-1)
    exit()

minX = min(setX)
cntMin = X.count(minX)
X[-1*cntMin-1],X[-1*cntMin] = X[-1*cntMin],X[-1*cntMin-1]
for x in X:
    print(x,end="")

以下の部分は例外処理。
入力の数字がすべて同じ場合と0以外の数字が1個しかないときは2番目に大きい数字が作れないので-1を出力している。

if len(setX) <= 1 or len(X) - X.count("0") <= 1:
    print(-1)
    exit()