# 資訊一乙Week12作業
## 題目敘述
給定一個數字 n,請你產生編號 1 ~ n 按照小到大排序且沒重複數字的卡片。編號 1
的卡片在最前面(top),編號 n 的卡片在最後面(bottom)。若目前有至少兩張牌以上的
話,需要按照以下的準則直到卡片只剩下一張:
● 將目前的 top 丟掉,再將新的 top 移到所有卡片的最後方。
以 1, 2, 3 這三張牌舉例子,1 為 top,3 為 bottom。首先會先將 top 的牌丟掉,目前
就剩下 2, 3,再來將新的 top,也就是 2 移到所有卡片的最後方,也就是變成 3, 2。
請寫一支程式能夠顯示丟掉卡片的順序及顯示出最後丟掉的一張牌。
輸入格式:
有多行測資,每行有一非負整數 n(0 <= n <= 50)。若 n 為 0 時,結束程式。
輸出格式:
根據每筆測資輸出兩行。第一行顯示丟掉卡牌的順序;第二行顯示最後一張牌的編
號。每行最前方或最後方都不會有多餘的空格,輸出格式請參考範例輸出。
___
範例輸入
Example 1.
7
19
Output:
Discarded cards: 1, 3, 5, 7, 4, 2
Remaining card: 6
Discarded cards: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 4, 8, 12, 16, 2, 10, 18, 14
Remaining card: 6
___
## 基本Function
### makenode
第一個就是...make node
```c
NODE* makenode(int val){
NODE* new = malloc(sizeof(NODE));
new->next = NULL;
new->val = val;
return new;
}
```
### push東西到stack裡面
啊好像用queue比較好
隨便啦都寫了
```c
void pushTop(NODE* obj, int val){
NODE* new = makenode(val);
new->next = obj->next;
obj->next = new;
}
```
### 取top值
```c
int takeTop(NODE* obj){
return obj->next->val;
}
```
### 取最上面的值之後刪除top
```c
int takeAndPop(NODE* obj){
int theVal = takeTop(obj);
NODE* temp = obj->next;
obj->next = obj->next->next;
free(temp);
return theVal;
}
```
基本上上面這些我相信一乙前幾個禮拜都有寫過
___
### 取最後一項的指標
就突然想到等一下應該會有需要用到取最後一項的指標的東東
所以就寫了以備不時之需
```c
NODE* takeButtonPtr(NODE* obj){
NODE* current = obj;
while (current->next){
current = current->next;
}
return current;
}
```
### 主要邏輯(圖解)
取最上面的值之後刪除top,然後再讓新top變buttom(最後一項)~~(是這樣翻嗎XD)~~
這裡就給大家圖解,用這張圖的邏輯就可以達到這個效果

```cpp
int takePopTurnToBack(NODE* obj, NODE* button){
int theVal = takeAndPop(obj);
button->next = obj->next;
obj->next = obj->next->next;
button->next->next = NULL;
//button = button->next;
return theVal;
}
```
## main函式~~沒有炸雞~~
```cpp
int main(){
//repeat
while (1){
//input
int target = 0;
scanf ("%d", &target);
//if input == 0, break
if (!target){
break;
}
//make the linked list
NODE* theList = makenode(0);
/*
use "stack way" to push the element into the list
so its actually "from target to 1",
but not "1 to target"
*/
for (int i=target; i>=1; --i){
pushTop(theList, i);
}
//no element discarded when target is 1
if (target == 1){
printf ("Discarded cards:\n");
}
else{
printf ("Discarded cards: ");
}
//if there have a second node, then we need to discard node
while (theList->next->next){
//NODE* button = takeButtonPtr(theList);
int ans = takePopTurnToBack(theList, takeButtonPtr(theList));
//if theres only one node after discarded a node, then it need to '\n'
if (!(theList->next->next)){
printf ("%d\n", ans);
}
else{
printf ("%d, ", ans);
}
}
//print last node value
printf ("Remaining card: %d\n", theList->next->val);
//free remaining node
free(theList->next);
free(theList);
}
}
```
我的寫法
寫得不好的話鞭小力一點