2025年2月21日 星期五

ZeroJudge 解題筆記:e974. 座位安排 (Seats)

作者:王一哲
日期:2025年2月21日



ZeroJudge 題目連結:e974. 座位安排 (Seats)

解題想法


這題在 Python 用 list 切片比較用索引值好寫,而且速度也快很多。

Python 程式碼


用 list 切片比較好寫,使用時間約為 38 ms,記憶體約為 4.5 MB,通過測試。
r, c, n = map(int, input().split())  # 列數 r,行數 c,週數 n
seat = [list(range(i*c+1, (i+1)*c+1)) for i in range(r)]  # 原來的座位表
for i in range(2, n+1):  # 依序處理第 2 ~ n 週
    if i%2 == 1:  # 單數週,所有人往後移一個座位,原本最後一排的人換到第一排
        seat = [seat[-1]] + seat[:-1]
    else:  # 雙數週,所有人往右橫移一個座位,原本最右邊的人則換到最左邊
        for j in range(r):  # 依序處理第 0 ~ r-1 列
            seat[j] = [seat[j][-1]] + seat[j][:-1]
for row in seat: print(*row)

用索引值設定串列中的值,速度會比用切片慢很多。使用時間約為 0.5 s,記憶體約為 4.5 MB,通過測試。
r, c, n = map(int, input().split())  # 列數 r,行數 c,週數 n
seat = [list(range(i*c+1, (i+1)*c+1)) for i in range(r)]  # 原來的座位表
for i in range(2, n+1):  # 依序處理第 2 ~ n 週
    if i%2 == 1:  # 單數週,所有人往後移一個座位,原本最後一排的人換到第一排
        tmp = seat[-1].copy()  # 第 r-1 列的編號先存到 tmp
        for j in range(r-1, -1, -1):  # 依序處理第 r-1 ~ 0 列
            for k in range(c):  # 依序處理第 0 ~ c-1 行
                if j == 0: seat[j][k] = tmp[k]  # 第 0 列,設定為 tmp
                else: seat[j][k] = seat[j-1][k]  # 其它列,向後移一行
    else:  # 雙數週,所有人往右橫移一個座位,原本最右邊的人則換到最左邊
        for j in range(r):  # 依序處理第 0 ~ r-1 列
            tmp = seat[j][-1]  # 每列第 c-1 行的編號先存到 tmp
            for k in range(c-1, -1, -1):  # 依序處理第 c-1 ~ 0 行
                if k == 0: seat[j][k] = tmp  # 第 j 列第 0 行,設定為 tmp
                else: seat[j][k] = seat[j][k-1]  # 其它行,向右移一行
for row in seat: print(*row)


C++ 程式碼


使用時間約為 5 ms,記憶體約為 376 kB,通過測試。
#include <iostream>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int r, c, n; cin >> r >> c >> n;  // 列數 r,行數 c,週數 n
    int seat[r][c];  // 原來的座位表,依序填入 1 ~ r*c
    for(int i=0; i<r; i++) {
        for(int j=0; j<c; j++) seat[i][j] = i*c+j+1;
    }
    for(int i=2; i<=n; i++) {  // 依序處理第 2 ~ n 週
        if (i%2 == 1) {  // 單數週,所有人往後移一個座位,原本最後一排的人換到第一排
            int tmp[c];  // 第 r-1 列的編號先存到 tmp
            for(int j=0; j<c; j++) tmp[j] = seat[r-1][j];
            for(int j=r-1; j>=0; j--) {  // 依序處理第 r-1 ~ 0 列
                for(int k=0; k<c; k++) {  // 依序處理第 0 ~ c-1 行
                    if (j == 0) seat[j][k] = tmp[k];  // 第 0 列,設定為 tmp
                    else seat[j][k] = seat[j-1][k];  // 其它列,向後移一行
                }
            }
        } else {  // 雙數週,所有人往右橫移一個座位,原本最右邊的人則換到最左邊
            for(int j=0; j<r; j++) {  // 依序處理第 0 ~ r-1 列
                int tmp = seat[j][c-1];  // 每列第 c-1 行的編號先存到 tmp 
                for(int k=c-1; k>=0; k--) {  // 依序處理第 c-1 ~ 0 行
                    if (k == 0) seat[j][k] = tmp;  // 第 j 列第 0 行,設定為 tmp
                    else seat[j][k] = seat[j][k-1];  // 其它行,向右移一行
                }
            }
        }
    }
    for(int i=0; i<r; i++) {  // 印出答案
        for(int j=0; j<c; j++) cout << seat[i][j] << " \n"[j == c-1];
    }
    return 0;
}


沒有留言:

張貼留言