PAT乙级 错误/知识点记录

本文提供PAT竞赛中的多项编程挑战题解答思路与代码片段,涵盖数组处理、字符串操作、排序算法等多个方面,帮助读者理解并掌握解决实际编程问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值