5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Python] paizaプログラミング練習問題 長テーブルのうなぎ屋 (paizaランク B 相当)

Last updated at Posted at 2018-10-19

paizaの練習問題をPython3でプログラミングします。

#問題
長テーブルのうなぎ屋 (paizaランク B 相当)
https://paiza.jp/learning/long-table

#ポイント

  • 円卓なので、最後の席まで座ったら1番目の席に戻ること
  • グループ全員が連続して座れること

#解答

unagi.py
# coding: UTF-8 

# ①入力処理:値取得、テーブル座席の配列準備
nm_array = input().split(" ")
seat_num = int(nm_array[0])
group_num = int(nm_array[1])
# print("シート数:", seat_num)
# print("グループ数;", group_num)

# 空席を0にする
seat = [0] * seat_num

count = 0
# ②グループ毎に空席確認
# グループ分のループ
for i in range(group_num):
    group_array = input().split(" ")
    group_person_num = int(group_array[0])
    sit_point = int(group_array[1])

    # インデックスのため-1する
    sit_point -= 1
    # print("グループの人数:", group_person_num)
    # print("着席開始位置:", sit_point)

    # グループ人数分のループ、空席確認
    empty_flg = True;
    for j in range(sit_point, sit_point+group_person_num):
        # 円卓処理
        if j >= seat_num:
            search_point = j - seat_num
        else:
            search_point = j
        # 空席確認
        if(seat[search_point] > 0):
            empty_flg = False
            break

    # ③席が空いていたら座る処理
    if empty_flg == True:
        # グループの人数分のループ、着席処理
        for j in range(sit_point,sit_point+group_person_num):
            # 円卓処理
            if j >= seat_num:
                search_point = j - seat_num
            else:
                search_point = j
            # print(search_point)
            # 着席処理
            seat[search_point] = 1
        # 座った人の人数を合算
        count += group_person_num
        
# 出力処理:座った人の人数を出力
print(count)

2018/10/21 追記
コメントをいただいたので、シンプルな別解を追記しました。

unagi2.py
def sit(n, m):
    """長テーブルのうなぎ屋の関数
    
    Arguments:
        n {int} -- シート数
        m {int} -- グループ数
    """
    # 空席をTrueとする
    sitable = [True] * n
    # グループ分のループ
    for _ in range(m):  
        people, seat = map(int, input().split())
        # 着席位置
        seats = range(seat, seat + people)
        # 空席確認(全員が座れるか確認)
        if all(sitable[seat % n] for seat in seats):
            # 座れた人数を報告
            yield people
            # 着席処理
            for seat in seats:
                sitable[seat % n] = False

# 出力処理:グループ毎に座れた人数を合計して出力
print(sum(sit(*map(int, input().split()))))
  • for _ in range(m)_(アンダースコア)は変数名を置き換えただけで、変数を使っていないことを表す。

  • yieldを実行すると、値を返却しつつ、現在の処理を中断したまま保持する。

  • all(sitable[seat % n] for seat in seats)all関数は引数内で指定した条件が全て満たされている場合、Trueを返す。

  • sit(*map(int, input().split()))*(アスタリスク)はリストはタプルや分解して渡し、sum関数で合計する。

#感想
アルゴリズム以前にPythonでリストの初期化方法を知りませんでした。
円卓処理のif文(座席数を超えたら最初に戻る)や、ループ処理の開始と終了(グループの1人目からグループの人数分)をどうすればいいかで悩みました。
うなぎ屋ではなく、回転寿司屋だと思って途中まで解いていました。

#関連
[ネタばれ] 長テーブルのうなぎ屋 (paizaランク B 相当)
[アルゴリズム問題 paiza練習問題 長テーブルのうなぎ屋]
(https://qiita.com/krppppp/items/a75205c9dcb4165ca2b4)

5
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?