---
# System prepended metadata

title: '[a271: 彩色蘿蔔](https://zerojudge.tw/ShowProblem?problemid=a271)'
tags: [zerojudge]

---

###### tags: `zerojudge`
# [a271: 彩色蘿蔔](https://zerojudge.tw/ShowProblem?problemid=a271)
>[name=Jia-Chi, Liang] [time=Fri, Aug 20, 2021, 21:15]
## 題目
在一個神奇的國度裡，有一種兔子，它只吃蘿蔔，且每天只吃一個，蘿蔔有四種顏色，分別為：紅蘿蔔，白蘿蔔，黃蘿蔔，發霉的蘿蔔（黑色），兔子吃了蘿蔔之後，體重會有不同的變化，紅蘿蔔吃了胖xg，白蘿蔔吃了胖yg，黃蘿蔔吃了瘦zg(醃黃蘿蔔真難吃...)，發霉的蘿蔔吃了瘦wg(附加狀態：中毒...)，現在給你x,y,z,w問你幾天後，兔子的體重！

p.s.中毒會使兔子每天瘦ng(中毒當天不算),且中毒狀態可累加，m是兔子初始的體重。早上先中毒，晚上才吃東西。

上面的敘述很重要，要仔細看！
## 輸入說明
第一行是測資的筆數，每筆測資第一行是x,y,z,w,n,m，第二行是一串數字，1代表紅蘿蔔，2代表白蘿蔔，3代表黃蘿蔔，4代表黑蘿蔔，0代表沒吃。這一行中的數字為兔子這段時間內所吃的食物。
## 輸出說明
請輸出兔子在那段時間後所剩的體重，如果體重有在任意時刻少於等於0請輸出："bye~Rabbit"(不含引號)，不然請印出結束時的體重。（詳情參照範例輸入輸出）

有可能問你第一天的體重歐！(就是問初始體重，也就是那行根本沒輸入)
例如如：
13 312 43 432 567
//空一行

輸出為：567
## Sample Input
4
5 3 2 4 3 10
1 1 2 3 3 3 3 4 3 3
5 3 2 4 3 10
1 1 2 3 3 3 3 4 3 3 2 2 2 2 2 2 2
5 3 2 4 3 10
4 1 3 3 1 1 2 2 1 1 3 1 1 1 1 4
10 3 2 2 1 5
1 4 4 0 0 4 1 2 2 2 0 0 2 2 0

## Sample Output
1g
bye~Rabbit
bye~Rabbit
bye~Rabbit

## 解題思維
如何讀取測資，卡了我很久。
### 大框架
* 讀第一個整數times，讓整個程式運作times次。
* 讀取測資第一行，把數字存到陣列:
    * g[0]=0 //因為0表示沒吃
    * g[1]=x //紅蘿蔔 + x
    * g[2]=y //白蘿蔔 + y
    * g[3]=z //黃蘿蔔 - z
    * g[4]=w //黑蘿蔔 - w
    * g[5]=n //中毒，每天 -n
    * g[6]=m //初始體重
讀取完畢後，把g[3]、g[4]設定成負的。

* 讀取測資第二行(eatN)
    * 如果已經中毒(isPoison==true)
        * 先扣體重:g[6]-=n;
        * 如果體重g[6]<=0，兔子死亡(isDie)設定成true，把剩下的數字讀完，結束迴圈。
    * 體重增加g[eatN]：
        * g[6]+=g[eatN];
        * 如果體重g[6]<=0，兔子死亡(isDie)設定成true，把剩下的數字讀完，結束迴圈。
    * 如果吃到黑蘿蔔(eatN==4)，
        *  n+=g[5];(n初始＝0, 每次中毒都要累加。)
        *  中毒(isPoison)設定成true。
* 輸出結果：
    * 如果兔子死亡，印出"bye~Rabbit\n"
    * 否則，印出體重(g[6])。
    
### 倒底該怎麼讀輸入？
* times  用 scanf("%d", &times);讀
* x, y, z, m , n, w, 用scanf("%d", &g[i])讀。後面加一個getchar()把\n讀掉。
* 讀測資第二行數字

### 讀取一行數字(c語言）
用getchar()一個一個讀取字元。
如果字元是\n，結束讀取。
如果字元是'0'~'9'，轉成整數，存起來。
其他字元不做事。
```c
char ch;
while((ch=getchar())!= '\n'){
    if(ch >= '0' && ch <= '9'){
        某變數= ch - '0';
    }
}
```



### 我遇到的bug

* 測資第一行我也用getchar()去讀，結果：
    1. 讀完times 這個整數後，用getchar()，會讀到times後面的\n，測資第一行就被跳過了。
    2. 大於10的數字，轉換會出錯。
* 如果中毒多次，扣的體重要累加，不能只扣n。
* 兔子死亡，用flag紀錄，到迴圈外面再print。我之前在迴圈裡面print，break之後，會多印出體重。
* 遇到兔字死亡，要用getchar()把剩下的數字讀完，之後才break。不然下一筆測資會讀錯。

## 程式碼
```c=
#include <stdio.h>

int main()
{
    int times, g[7], eatN, isPoison, isDie, n;
    char ch;
    scanf("%d", &times);
    while(times--){//讓整個程式運作times次
        g[0]=0;
        //讀取測資第一行
        for (int i=1; i<=6; i++) scanf("%d", &g[i]);
        g[3] = -g[3];//把g[3]、g[4]設定成負的。
        g[4] = -g[4];
        ch = getchar();//讀走換行符號
        //printf("get: %d Line 1\n", ch);
        //讀取測資第二行(eatN)
        isPoison = 0;
        isDie = 0;
        n = 0;//中毒扣分初始 = 0
        while((ch=getchar())!= '\n'){
                //printf("get: %c\n",  ch);
                if (ch >= '0' && ch <='9'){
                    eatN = ch - '0';
                    //如果已經中毒
                    if (isPoison){
                        g[6]-=n;//先扣體重
                        if (g[6]<=0){//如果體重g[6]<=0，印出"bye~Rabbit"，結束迴圈。
                            isDie=1;
                            while((ch=getchar())!= '\n');
                            break;
                        }
                    }

                    //體重增加g[eatN]
                    g[6]+=g[eatN];
                    if (g[6]<=0){//如果體重g[6]<=0，印出"bye~Rabbit"，結束迴圈。
                            isDie=1;
                            while((ch=getchar())!= '\n');
                            break;
                    }
                    if (eatN==4) {
                        n += g[5];
                        isPoison = 1;//如果吃到黑蘿蔔，中毒(isPoison)設定成true
                    }
                }
            }
            if (isDie || g[6]==0) printf("bye~Rabbit\n");
            else printf("%dg\n", g[6]);
    }

    return 0;
}


```