20230610
上週作業檢討
盧冠綸 @ Sprout 2023
管理貨櫃
操作:
1. 插入貨櫃,把編號由小到大排。
2. 移除 指定重量的貨櫃。
插入(架構)
Container* insert(Container* head, int index, int weight){
Container *newone = new Container;
// TODO: 初始化 newone
if (head == nullptr){
return newone;
}else if (新貨櫃的編號,小於head的編號){
// TODO: 把新貨櫃插在最前面
}else if (新貨櫃的編號,小於tail的編號){
// TODO: 把新貨櫃插在中間正確的地方
}else{ // 新貨櫃的編號,大於tail的編號
// TODO: 把新貨櫃插在最後面
}
更詳細的做法在下一頁。
修改有寫 TODO 的部分即可。
插入(詳細架構)
Container* insert(Container* head, int index, int weight){
Container *newone = new Container;
// TODO: 初始化 newone
if (head == nullptr) return newone;
// 新貨櫃的編號,小於head的編號
if (head -> index < newone -> index){
// TODO: 把 newone 插在 head 前面
return newone;
}
// 新貨櫃的編號,小於tail的編號
Container *temp = head;
while (temp 不是 tail){ // TODO: 怎麼判斷 temp 是不是 tail ?
if (temp -> next -> index > newone -> index){
// TODO: 把 newone 插在 temp 和 temp->next 之間
return head;
}
temp = temp -> next;
}
// 如果迴圈跑完了但還沒 return,代表 temp 已經是 tail,且 newone 的 id 比他大。
// 新貨櫃的編號,大於tail的編號
// TODO: 把 newone 插在 temp 後面
return head;
}
移除(架構)
Container* remove(Container* head, int max_weight){
if (head == nullptr){
// 什麼都不做
}else if (要移除的貨櫃是 head){
// 把該貨櫃移除
// head 改成 head 的下一個
}else if (要移除的貨櫃不是 head){
// 把該貨櫃移除
}else{ // 找不到要移除的貨櫃
// 什麼都不做
}
}
移除(詳細架構)
Container* remove(Container* head, int max_weight){
if (head == nullptr) return nullptr;
// 要移除的貨櫃是 head
if (head -> weight == max_weight) return head -> next;
// 要移除的貨櫃不是 head
Container *prev = head, *now = prev -> next;
while (now != nullptr){
if (now -> weight == max_weight){
// TODO: 把 now 從 linked list 中移除
return head;
}
prev = prev -> next;
now = now -> next;
}
// 找不到要移除的貨櫃
return head;
參考解答
Container* insert(Container* head, int index, int weight){
Container *newone = new Container;
newone -> index = index;
newone -> weight = weight;
newone -> next = head;
if (head == nullptr) return newone;
if (head -> index > newone -> index) return newone;
Container *temp = head;
while (temp -> next != nullptr){
if (temp -> next -> index > newone -> index){
newone -> next = temp -> next;
temp -> next = newone;
return head;
}
temp = temp -> next;
}
newone -> next = nullptr;
temp -> next = newone;
return head;
}
Container* remove(Container* head, int max_weight){
if (head == nullptr) return nullptr;
if (head -> weight == max_weight) return head -> next;
Container *temp = head, *next = head -> next;
while (next != nullptr){
if (next -> weight == max_weight){
temp -> next = next -> next;
return head;
}
next = next -> next;
temp = temp -> next;
}
return head;
}
奇怪的火車問題
輸入資料:初始化你的每個 linked list。
操作:
1 x:把第 x 台火車反轉。
2 a b:把第 a 台火車,第一節車廂以外者,
接到第 b 台火車後面。
3 x:輸出第 x 台火車。
架構
因為有「反轉」,如果用 doubly linked list,
應該會比較方便。
(當然你要用一般的 linked list 寫也不是不行)
struct box{
int id;
box *prev;
box *next;
};
架構
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
int num, step;
box *head[10001]; // 存所有火車的頭
box *tail[10001]; // 存所有火車的尾
cin >> num >> step;
for (int i=1 ; i<=num ; i++){
// TODO: 1. 輸入第 i 台火車的資料
// 2. 產生第 i 個 linked list
// 3. 維護 head[i] 和 tail[i]
}
for (int i=0 ; i<step ; i++){
int command, index1, index2;
cin >> command;
if (command == 1){
cin >> index1;
// TODO: 反轉第 index1 台火車
}
if (command == 2){
cin >> index1 >> index2;
// TODO: 把 index1 火車後面,接到 index2 後面
}
if (command){
cin >> index1;
// TODO: 印出第 index1 台火車
}
}
}
處理輸入
for (int i=0 ; i<num ; i++){
head[i] = nullptr;
tail[i] = nullptr;
int count; // 第 i 台火車的長度
cin >> count;
for (int j=0 ; j<count ; j++){
int id;
cin >> id;
box *temp = new box;
temp -> id = id;
if (j == 0){
// TODO: 更新 head[i]
// TODO: 更新 tail[i]
// TODO: 調整 temp 的 prev 和 next
}
else{
// TODO: 調整 tail[i] 的 next
// TODO: 調整 temp 的 prev 和 next
// TODO: 更新 tail[i]
}
}
}
// TODO: 1. 輸入第 i 台火車的資料
// 2. 產生第 i 個 linked list
// 3. 維護 head[i] 和 tail[i]
前一頁的 TODO:
操作一
box *temp = head[index];
while (temp != nullptr){
box *temp2 = temp -> next;
// TODO: 把 temp -> prev 跟 temp -> next 兩個指針對調
temp = temp2;
}
反轉第 index 台火車:
操作二
// 如果第 index1 台火車長度在 1 以下,就什麼都不做
if (head[index1] == nullptr) continue;
if (head[index1] == tail[index1]) continue;
// 如果第 index2 台火車長度為 0
if (head[index2] == nullptr){
box *cat = head[index1] -> next; // 要接在 index2 後的車廂
head[index1] -> next = // TODO
if (cat != nullptr) cat -> prev = // TODO
// TODO: 更新 head[index2], tail[index2], tail[index1]
}
// 如果第 index2 台火車長度非 0
else{
box *cat = head[index1] -> next; // 要接在 index2 後的車廂
head[index1] -> next = // TODO
if (cat != nullptr) cat -> prev = // TODO
tail[index2] -> next = // TODO
// TODO: 更新 tail[index1]、tail[index2]
}
反轉第 index 台火車:
操作三
box *temp = head[index];
while (temp != nullptr){
cout << temp -> id << " ";
temp = temp -> next;
}
cout << endl;
印出第 index 台火車:
總架構
#include <iostream>
#include <string>
using namespace std;
struct box{
int id;
box *prev;
box *next;
};
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
int num, step;
box *head[10001]; // 存所有火車的頭
box *tail[10001]; // 存所有火車的尾
cin >> num >> step;
// 處理輸入
for (int i=1 ; i<=num ; i++){
head[i] = nullptr;
tail[i] = nullptr;
int count; // 第 i 台火車的長度
cin >> count;
for (int j=0 ; j<count ; j++){
int id;
cin >> id;
box *temp = new box;
temp -> id = id;
if (j == 0){
head[i] = // TODO
tail[i] = // TODO
temp -> prev = // TODO
temp -> next = // TODO
}
else{
tail[i] -> next = // TODO
temp -> prev = // TODO
temp -> next = // TODO
tail[i] = // TODO
}
}
}
// 處理操作
for (int i=0 ; i<step ; i++){
int command, index1, index2;
cin >> command;
// 反轉第 index1 台火車
if (command == 1){
cin >> index1;
box *temp = head[index1];
while (temp != nullptr){
box *temp2 = temp -> next;
// TODO: 把 temp -> prev 跟 temp -> next 兩個指針對調
temp = temp2;
}
// TODO: 交換 head[index1] 和 tail[index1]
}
// 把 index1 火車後面,接到 index2 後面
if (command == 2){
cin >> index1 >> index2;
// 如果第 index1 台火車長度在 1 以下,就什麼都不做
if (head[index1] == nullptr) continue;
if (head[index1] == tail[index1]) continue;
// 如果第 index2 台火車長度為 0
if (head[index2] == nullptr){
box *cat = head[index1] -> next; // 要接在 index2 後的車廂
head[index1] -> next = // TODO
if (cat != nullptr) cat -> prev = // TODO
head[index2] = // TODO
tail[index2] = // TODO
tail[index1] = // TODO
}
// 如果第 index2 台火車長度非 0
else{
box *cat = head[index1] -> next; // 要接在 index2 後的車廂
head[index1] -> next = // TODO
if (cat != nullptr) cat -> prev = // TODO
tail[index2] -> next = // TODO
tail[index2] = // TODO
tail[index1] = // TODO
}
}
// 印出第 index1 台火車
if (command == 3){
cin >> index1;
box *temp = head[index1];
while (temp != nullptr){
cout << temp -> id << " ";
temp = temp -> next;
}
cout << endl;
}
}
}
參考解答
#include <iostream>
#include <string>
using namespace std;
struct box{
int id;
box *prev;
box *next;
};
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
int num, step;
box *head[10001]; // 存所有火車的頭
box *tail[10001]; // 存所有火車的尾
cin >> num >> step;
// 處理輸入
for (int i=1 ; i<=num ; i++){
head[i] = nullptr;
tail[i] = nullptr;
int count; // 第 i 台火車的長度
cin >> count;
for (int j=0 ; j<count ; j++){
int id;
cin >> id;
box *temp = new box;
temp -> id = id;
if (j == 0){
head[i] = temp;
tail[i] = temp;
temp -> prev = nullptr;
temp -> next = nullptr;
}
else{
tail[i] -> next = temp;
temp -> prev = tail[i];
temp -> next = nullptr;
tail[i] = temp;
}
}
}
// 處理操作
for (int i=0 ; i<step ; i++){
int command, index1, index2;
cin >> command;
// 反轉第 index1 台火車
if (command == 1){
cin >> index1;
box *temp = head[index1];
while (temp != nullptr){
box *temp2 = temp -> next;
temp -> next = temp -> prev;
temp -> prev = temp2;
temp = temp2;
}
swap(head[index1], tail[index1]);
}
// 把 index1 火車後面,接到 index2 後面
if (command == 2){
cin >> index1 >> index2;
// 如果第 index1 台火車長度在 1 以下,就什麼都不做
if (head[index1] == nullptr) continue;
if (head[index1] == tail[index1]) continue;
// 如果第 index2 台火車長度為 0
if (head[index2] == nullptr){
box *cat = head[index1] -> next; // 要接在 index2 後的車廂
head[index1] -> next = nullptr;
if (cat != nullptr) cat -> prev = nullptr;
head[index2] = cat;
tail[index2] = tail[index1];
tail[index1] = head[index1];
}
// 如果第 index2 台火車長度非 0
else{
box *cat = head[index1] -> next; // 要接在 index2 後的車廂
head[index1] -> next = nullptr;
if (cat != nullptr) cat -> prev = tail[index2];
tail[index2] -> next = cat;
tail[index2] = tail[index1];
tail[index1] = head[index1];
}
}
// 印出第 index1 台火車
if (command == 3){
cin >> index1;
box *temp = head[index1];
while (temp != nullptr){
cout << temp -> id << " ";
temp = temp -> next;
}
cout << endl;
}
}
}
謝謝大家
Copy of 20230610 上週作業檢討
By allen522019
Copy of 20230610 上週作業檢討
- 149