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);
}