1. 程式人生 > >【學習心得】-刷浙大乙級PAT1001-1005題後心得 c++(一)

【學習心得】-刷浙大乙級PAT1001-1005題後心得 c++(一)

9月份入學研究生,因為本身機械跨考計算機,所以在程式設計方面的能力簡直不能直視,直接被一起入學的同學們甩了好幾條街。同時也在導師的再三敦促下刷下浙大PAT的題。訓練下自己的程式設計能力。(當然自己也是非常想提升下程式設計能力)。所以打算一邊刷題一邊學習(暑假有斷斷續續看過c++,因為是斷斷續續所以到了開學基本都忘了,真是心累)。這裡我先放上我這3天來的結果1001-1005,(是不是刷的很慢,還是邊看部落格上的程式邊寫的)。
下面來看下題目。

1001.害死人不償命的(3n+1)猜想 (15)

對任何一個自然數n,如果它是偶數,那麼把它砍掉一半;如果它是奇數,那麼把(3n+1)砍掉一半。這樣一直反覆砍下去,最後一定在某一步得到n=1。

對於第一題,其實主要還是一個分類的問題,if分類,whlie迴圈基本就搞定了。難度也不大,在不看答案的情況下完成。
程式碼如下:

#include<iostream>
int main() {
    int n = 0;
    int x = 3;
    std::cin >> x ;
    while (x != 1) {
        if (x % 2) {
            x = (3 * x + 1) / 2;
            n++;
        }
        else {
            x = x / 2;
            n++;
        }

    }
    std
::cout << n << std::endl; }

對其的改進:如果說改進的話我想就是輸入輸出時std::cinstd::cout對名稱空間的引用,在開頭加一個using namespace std可以在下面對與輸入輸出流的引用時不用在加上std::

看第二題

1002.寫出這個數 (20)

讀入一個自然數n,計算其各位數字之和,用漢語拼音寫出和的每一位數字。

對於第二題,我剛開始的想法是直接cin輸入一個數賦值給n,之後通過while迴圈求出每個位數上的總和sum,最後通過switch提供的多個分支條件來做分類輸出。最後結果基本和題目要求的一樣,但是最後在提交程式碼後的幾個踩分點沒有得分。先把程式碼附上:

#include<iostream>

using namespace std;

int main() {
    int x = 0;
    int sum = 0;
    int n=0;
    int a;
    cin >> x;
    while (x != 0) {
        sum = sum + (x % 10);
        x = x / 10;
    }
    a = sum;
    while (a != 0) {
        a = a / 10;
        n++;
    }
    while (sum != 0) {
        switch (sum % 10) {
            case 0:cout << "ling" ;break;
            case 1cout << "yi" ;break;
            case 2:cout << "er" ;break;
            case 3:cout << "san" ;break;
            case 4:cout << "si" ;break;
            case 5:cout << "wu" ;break;
            case 6:cout << "liu" ;break;
            case 7:cout << "qi" ;break;
            case 8:cout << "ba" ;break;
            case 9:cout << "jiu" ;break;
    }
        n--;
        sum = sum / 10;
        if (n>=1) {
        cout << " ";
        }
    }
}

後來對比部落格上已有人寫過的程式碼

#include<iostream>
#include<string>
#include<vector>
using namespace std;

string Display(int temp) {
    string str;
    switch (temp) {
    case 0:str = "ling"; break;
    case 1:str = "yi"; break;
    case 2:str = "er"; break;
    case 3:str = "san"; break;
    case 4:str = "si"; break;
    case 5:str = "wu"; break;
    case 6:str = "liu"; break;
    case 7:str = "qi"; break;
    case 8:str = "ba"; break;
    case 9:str = "jiu"; break;
    }
    return str;
}
int main() {                                               
    char mun[101] = { 0 };
    char *p_mun = mun;
    int sum = 0;
    int temp = 0;
    int i = 0;
    cin >> mun;
    while (*p_mun != '\0') {
        sum = sum + (*p_mun - '0');
        *p_mun++;
    }
    vector<int>vec;
    while (sum != 0) {
        vec.push_back(sum % 10);
        sum = sum / 10;
    }
    for (temp = vec.size() - 1; temp > 0; temp--) {
        cout << Display(vec[temp]) << ' ';
    }
    cout << Display(vec[temp]) ;
    return 0;
}

再回來看自己的程式碼,可以發現在數值轉化為字母的步驟上,我的程式中對switch的分支處理上,我在每個分支後面都使用了COUT輸出流;但下面的程式碼則是先構建vector容器,通過將sum的值對映至容器中,在通過for將vec容器中的值通過對Display的呼叫輸出返回值。
其實在步驟上可能是我的更加簡單粗暴,但是這使程式碼的架構更加複雜,編譯過程耗死過多。
同時對於第二題的學習,我也學習到了c++中vector容器的使用,包括其一些簡單的操作命令。
(待續)