【佇列】【利用Flag最佳化】簡單的資料結構

peterzh6發表於2024-10-19

https://ac.nowcoder.com/acm/contest/22669/K

小技巧

  1. 遍歷list且最後一個元素後沒有多餘空格
for (auto it = mylist.begin(); it != mylist.end(); ++it) {
	if (it != mylist.begin()) printf(" ");
	printf("%d", *it);
}
  1. 學會使用rbegin() reng()反向遍歷容器
    rbegin() 和 end() 在使用上的主要區別在於它們迭代的方向不同。具體來說:

rbegin() 返回一個 反向迭代器,它指向容器的最後一個元素,迭代的方向是 從尾到頭。
end() 返回一個 正向迭代器,它指向容器的最後一個元素的 下一個位置,迭代的方向是 從頭到尾。
區別詳解
rbegin() 和 rend()(反向迭代):

rbegin() 返回指向容器最後一個元素的反向迭代器,rend() 返回指向容器第一個元素之前的位置的反向迭代器。
反向迭代器使你可以從容器的最後一個元素開始向前遍歷。
begin() 和 end()(正向迭代):

begin() 返回指向容器第一個元素的迭代器,end() 返回指向容器最後一個元素之後的迭代器。
正向迭代器是從容器的第一個元素開始向後遍歷。

  1. 對於多次反轉列表,考慮使用reversed標誌,減少重複反轉,實現“懶反轉”。本題如果按部就班地反轉,會超時
#include <bits/stdc++.h>

std::list<int> mylist;
bool reversed = false;  // 用於記錄當前的順序是否被反轉

int main() {
    int n, m, a, op;
    scanf("%d %d", &n, &m);
    
    while (m--) {
        scanf("%d", &op);
        
        if (op == 1) {  // 從前面插入
            scanf("%d", &a);
            if (reversed) {
                mylist.push_back(a);  // 如果當前被反轉了,則從後面插入
            } else {
                mylist.push_front(a);  // 正常順序下從前面插入
            }
        } else if (op == 2) {  // 從前面刪除
            if (reversed) {
                mylist.pop_back();  // 當前被反轉,從後面刪除
            } else {
                mylist.pop_front();  // 正常順序下從前面刪除
            }
        } else if (op == 3) {  // 從後面插入
            scanf("%d", &a);
            if (reversed) {
                mylist.push_front(a);  // 被反轉後從前面插入
            } else {
                mylist.push_back(a);  // 正常順序下從後面插入
            }
        } else if (op == 4) {  // 從後面刪除
            if (reversed) {
                mylist.pop_front();  // 被反轉後從前面刪除
            } else {
                mylist.pop_back();  // 正常順序下從後面刪除
            }
        } else if (op == 5) {  // 翻轉序列
            reversed = !reversed;  // 只修改標誌位,不真正翻轉序列
        } else if (op == 6) {  // 輸出當前元素個數和順序
            printf("%zu\n", mylist.size());
            if (reversed) {
                for (auto it = mylist.rbegin(); it != mylist.rend(); ++it) {
                    if (it != mylist.rbegin()) printf(" ");
                    printf("%d", *it);
                }
            } else {
                for (auto it = mylist.begin(); it != mylist.end(); ++it) {
                    if (it != mylist.begin()) printf(" ");
                    printf("%d", *it);
                }
            }
            printf("\n");
        } else if (op == 7) {  // 排序
            mylist.sort();  // 直接排序,因為 list 的 sort 內部實現是穩定的 O(n log n)
            if (reversed) {
                mylist.reverse();  // 如果當前被反轉,需要再反轉回來
            }
        }
    }
    
    return 0;
}

相關文章