本サイトAIZU ONLINE JUDGE ITP1_9_B へはこちらから
問題:シャッフル
1つのアルファベットが描かれた n 枚のカードの山をシャッフルします。
1回のシャッフルでは、下から h 枚のカードをまとめて取り出し、それを残ったカードの山の上に積み上げます。
カードの山は以下のように1つの文字列で与えられます。
abcdeefab
最初の文字が一番下にあるカード、最後の文字が一番上にあるカードを示しています。
例えば、これを h が 4 でシャッフルすると、最初の4文字 abcd が、残りの文字 eefab の末尾へ連結されるので以下のようになります:
eefababcd
このシャッフルを何回か繰り返します。
カードの山の最初の並び(文字列)と h の列を読み込み、最後の並び(文字列)を出力するプログラムを作成して下さい。
Input
複数のデータセットが入力として与えられます。各データセットは以下の形式で与えられます:
最初の並びを表す文字列
シャッフル回数 m
h1
h2
.
.
hm
最初の並びを表す文字列が “-” のとき入力の終わりとします。
Constraints
- 1 ≤ 文字列の長さ≤ 200
- 1 ≤ m ≤ 100
- 1 ≤ hi < 文字列の長さ
- データセットの数は10を超えない
Output
各データセットに対して、最後の並び(文字列)を1行に出力して下さい。
Sample Input
aabc
3
1
2
1
vwxyz
2
3
4
-
Sample Output
aabc
xyzvw
解答例
while True:
cards = input()
if cards == "-":
break
m = int(input())
for _ in range(m):
sh = int(input())
former = cards[:sh]
later = cards[sh:]
cards = later+former
print(cards)
解説
以下のように解いていきます。
while文を使用し、入力処理を行う
ある条件まで入力を続ける場合はwhile文とif文を組み合わせて、入力処理を行います。
# if文の条件式に当てはまるまでループ処理を続ける
while True:
処理
# この条件式に当てはまる場合、break文でループ処理を終了する
if 条件式:
break
今回は、whileループ内でまずinput関数を使用し、シャッフルする文字列を受け取ります。
次にif文を使用し、文字列に “-“ が入力された場合にbreak文で処理を終了します。
“-“ 以外の場合はint関数の引数にinput関数を設定し、シャッフル回数である整数を読み込みます。
# 終了条件に当てはまるまで処理を続ける
while True:
# シャッフルする文字列を受け取る
cards = input()
# 文字列"-"が入力された場合にbreak文で処理を終了
if cards == "-":
break
# シャッフル回数である整数を受け取る
m = int(input())
※サイト内「AIZU ONLINE JUDGE ITP1_1_Bをpythonで解いてみた」の、input関数とはに使用方法が書かれておりますのでぜひご覧ください。
※サイト内「AIZU ONLINE JUDGE ITP1_3_Cをpythonで解いてみた」の、break文とはに使用方法が書かれておりますのでよかったらご覧ください。
シャッフル処理と、シャッフル後の文字列の表示
まず、1.while文を使用し、入力処理を行うで読み込んだシャッフル回数分ループを回します。
続いて、for文内ではシャッフルする区切りである整数を読み込んだ後、リストのスライスを利用してカードをシャッフルします。
まずは、ここで使用するスライスについて説明します。
スライスとは
リストのスライスという機能を使うことで、開始位置のインデックスから終了位置のインデックスまでの要素を含む新しいリストを取得することができます。
リスト[開始インデックス:終了インデックス]
イメージはこのような感じです。
開始インデックスと終了インデックスの間の文字を取得します。
sample_lst = ["P", "y", "t", "h", "o", "n"]
# インデックス 1 から 4 までの要素を取得する
print(sample_lst[1:4])
# 出力
['y', 't', 'h']
# インデックス 0 から 3 までの要素を取得する
print(sample_lst[0:3])
# 出力
['P', 'y', 't']
# インデックス 3 から 4 の要素を取得する
print(sample_lst[3:4])
# 出力
['h']
スライス機能を使用するときに、開始インデックスまたは終了インデックスを省略することができます。
開始インデックスを省略した場合は 0 が指定されたものとみなされます。 0 はリストの最初の要素のインデックスなので、開始インデックスを省略した場合はリストの最初の要素から指定した終了インデックスまでが範囲となります。
sample_lst = ["P", "y", "t", "h", "o", "n"]
# インデックスの最初から 4 までの要素を取得する
print(sample_lst[:4])
# 出力
['P', 'y', 't', 'h']
# インデックス 2 から最後までの要素を取得する
print(sample_lst[2:])
# 出力
['t', 'h', 'o', 'n']
今回は、シャッフルする区切りの前後で新しく区切りの前former、区切りの後laterとして文字列を分け、反転して連結します。これをシャッフル回数分繰り返した後に、print文で表示します。
for i in range(m):
# シャッフルする区切りの読み込み
sh = int(input())
# 区切った前の部分を変数formerに設定
former = cards[:sh]
# 区切った後の部分を変数laterに設定
later = cards[sh:]
# 前後を入れ替える
cards = later+former
print(cards)
※サイト内「AIZU ONLINE JUDGE ITP1_3_Aをpythonで解いてみた」の、for文とはに使用方法が書かれておりますのでよかったらご覧ください。
最後に、もう一度プログラムを確認してみましょう。
# 終了条件に当てはまるまで処理を続ける
while True:
# シャッフルする文字列を受け取る
cards = input()
# 文字列"-"が入力された場合にbreak文で処理を終了
if cards == "-":
break
# シャッフル回数である整数を受け取る
m = int(input())
# シャッフル回数であるm回for文を回す
for _ in range(m):
# シャッフルする区切りの読み込み
sh = int(input())
# 区切った前の部分を変数formerに設定
former = cards[:sh]
# 区切った後の部分を変数laterに設定
later = cards[sh:]
# 前後を入れ替える
cards = later+former
print(cards)
コメント