1. 程式人生 > >PAT乙級 錯誤/知識點記錄

PAT乙級 錯誤/知識點記錄

1011

注意 A與B的範圍均為[−2​^31​​,2​^31​​],而C = A + B,所以至少需要64位的long型。

 

1012(第7個檢查點未通過)

#include <iomanip>

cout<<setprecision(2)<<a;
int a[6];
int count[6]; 
for(i=0;i<5;i++){
    count[i] = 0;
    a[i] = 0;
}

此處如果不對陣列內元素賦初值,在sublime的自定義g++編譯器中結果正確,但是無法通過PAT檢查點。

 

1013

注意輸出要求!

每十個換行,每行末尾無空格。

for(i=m-1;i<n;i++){
    if(i - m + 1 > 0 && (i - m + 1)%10 == 0) cout<<endl;
    cout<<prime[i];
    if(i != n-1 && (i - m + 2)%10 != 0) cout<<' ';
}

*參考大佬做法,判斷素數的函式(https://www.liuchuo.net/archives/530):

bool isprime(int a) {
    for (int i = 2; i * i <= a; i++)
        if(a % i == 0) return false;
    return true;
}

 

1014(第六個檢查點未通過)

ascii碼常用:數字從48開始,大寫字母從65開始,小寫字母從97開始。

map需要#include<map>

    map<char, string> mapday;
    mapday['A'] = "MON";mapday['B'] = "TUE";mapday['C'] = "WED";
    mapday['D'] = "THU";mapday['E'] = "FRI";mapday['F'] = "SAT";
    mapday['G'] = "SUN";

設定bool變數day_get和hour_get來判斷當前獲得的相同字元是否賦給day/hour,且當兩者均為真的時候結束搜尋跳出迴圈:

    bool day_get = false;
    bool hour_get = false;

    for(i=0;i<strlen(str1);i++){
        ascii = int(str1[i]);
        if(str1[i] == str2[i] && ascii >= 65 && ascii <= 90 && !day_get){
            day_get = true;
            day = str1[i];
            continue;
        }
        if(str1[i] == str2[i] && ascii >= 65 && ascii <= 78 && day_get){
            hour = to_string(ascii - 55);
            hour_get = true;
        }
        if(str1[i] == str2[i] && ascii >= 48 && ascii <= 57 && day_get){
            hour = "0" + to_string(ascii - 48);
            hour_get = true;
        }
        if(day_get && hour_get) break;
    }

*使用printf控制輸出格式:

printf("%02d:%02d", m, pos);

%02d中,0指定用於填充的字元,注意換成其他數字的話會變成不同長度的tab,2指定需要達到的長度。

 

1015 德才論

*多層比較的函式寫法:

int cmp(struct node a, struct node b) {
    if ((a.de + a.cai) != (b.de + b.cai))
        return (a.de + a.cai) > (b.de + b.cai);
    else if (a.de != b.de)
        return a.de > b.de;
    else
        return a.num < b.num;
}

 

1018

*快速得到三個元素陣列的最大元素下標:

    int maxjia = jia[0] >= jia[1] ? 0 : 1;
    maxjia = jia[maxjia] >= jia[2] ? maxjia : 2;
    int maxyi = yi[0] >= yi[1] ? 0 : 1;
    maxyi = yi[maxyi] >= yi[2] ? maxyi : 2;

題目要求解不唯一時輸出按字母序最小的解,所以乾脆在最開始設定陣列時就認為0號為B,1號為C,2號為J。

 

1019 

string s;

s.insert(0, 4 – s.length(), ‘0’);

//用來給不足4位的時候前面補0

sort()函式:預設升序,降序需要自定義函式cmp()。

需要#include <algorithm>

bool cmp(char a, char b) {return a > b;}

sort(a.begin(), a.end(), cmp);
sort(b.begin(), b.end());

 

1020 月餅

控制小數點後小數位數:

#include <iomanip>

cout<<setiosflags(ios::fixed)<<setprecision(2)<<profit;

注意浮點數和整數的選擇!

*對於有多個引數的結構,希望按照某一引數排序,可以定義結構體並使用sort,寫好對應的cmp()函式即可:

struct mooncake{
    float mount, price, unit;
};

int cmp(mooncake a, mooncake b) {
    return a.unit > b.unit;
}

sort(a.begin(), a.end(), cmp);

*printf控制小數點後位數非常方便:

printf("%.2f",result);

 

1024 最後一個檢查點未通過

 

1025

刪除vector指定位置元素:

vector<node>::iterator iter = node_vec.begin() + i;
node_vec.erase(iter);

控制整數輸出格式,不足前面用‘0’補足:

#include <iomanip>

cout<<setw(5)<<setfill('0')<<new_node_vec[j].addr<<' '<<new_node_vec[j].value<<' '<<new_node_vec[(j+2)%k].next<<endl;

*利用algorithm標頭檔案中的reverse函式(針對陣列等列表):

    for (int i = 0; i < (sum - sum % k); i += k)
        reverse(begin(list) + i, begin(list) + i + k);
    for (int i = 0; i < sum - 1; i++)
        printf("%05d %d %05d\n", list[i], data[list[i]], list[i + 1]);
    printf("%05d %d -1", list[sum - 1], data[list[sum - 1]]);

 

1026

C++的round需要自己實現:

a = int(b + 0.5);

 

1027 第2、3個檢測點PE

PE原因:每一行的符號後面其實是沒有空格的,直接換行即可。

abs()函式在stdlib.h標頭檔案裡。

 

1028

陣列轉字串:

#include <string.h>

char date[11];
cin>>date;
string str_date;
str_date = date;

開始第四個檢查點PE,猜想是有效人數為0時的異常。於是在統計完人數後加個if,如果人數為0直接return 0結束程式。

*可以考慮有效生日錄入和最值記錄在一輪迴圈內進行。

*我使用了字串比較,其實是因為不擅長輸入提取。事實上可以使用scanf:

scanf("%d/%d/%d",&year, &month, &day);

 

1029 最後一個檢查點未通過

*全部記下來吧還是

#include <iostream>
#include <cctype>
using namespace std;
int main() {
    string s1, s2, ans;
    cin >> s1 >> s2;
    for (int i = 0; i < s1.length(); i++)
        if (s2.find(s1[i]) == string::npos && ans.find(toupper(s1[i])) == string::npos)
            ans += toupper(s1[i]);
    cout << ans;
    return 0;
}

 

1030

倒數第二個檢查點超時,氣泡排序效率太低。

最後一個檢查點第一次未通過,將陣列換成long型後通過。

*排序改成sort()

*發現了之前做法的一個嚴重問題:默認了數列中最大的數就是所給數中的最大數。事實上數列中的最大數同時影響M*P的值和比它小的數的個數。

 

1031 第三個檢查點未通過

 

1033

memset 用於陣列的整體賦(相同)值:

bool hashtable[256];
memset(hashtable,true,sizeof(hashtable));

參考牛克網一位大神的方法:

建立256位的bool陣列,每一位儲存以下標為acsii碼的字元。

先使用memset將陣列整體初始化為true,掃描一遍壞鍵列表,將壞鍵在bool陣列中的對應值設為false。這樣就不需要每次都重新掃描壞鍵列表了。

 

*為了防止第一行是空的,最好使用getline:

  string bad, should;
  getline(cin, bad);
  getline(cin, should);

*判斷一個字母的大寫形式是否在指定字串中:

#include <cctype>


if (bad.find(toupper(should[i])) != string::npos) continue;

 

 

1034

最大公約數求法:

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a%b);
}