PAT B错题笔记【完结】

一开始发现gcc运行和g++运行有差别
最好还是gcc—c g++—c++

B1001

正确且无需修改

B1002

错误原因:最后一个拼音数字后没有空格
改进:合并for循环
注意:to_string()c+11

B1003

错误原因:应该输出YES NO却输出yes no
改进:合并for循环

B1004

错误原因:段错误 应该要把结构体数组设置为10000
注意sort(ve.begin(),ve.end(),cmp); 包左不包右

B1005

改进

 if(a[n]%2==0)
     a[n]=a[n]/2;
 else
     a[n]=(3*a[n]+1)/2;
if(a[n]%2=0)
     a[n]=(3*a[n]+1);
     a[n]=a[n]/2;

学习第一个数据不用空格 以后都要空格

一开始flag==0
if(flag==1)cout<<" ";
cout<<v[i];
flag==1;这样除第一次循环都要加空格

B1006

正确且无需修改

B1007

改进:我的方法是找出素数 再判断是否差2 更加简便的方法是差2的数判断是否都是素数 这样就可以少进行一次循环
注意:如何构建一个素数表

bool isPrime(int number)
{
    for(int i=2;i*i<=number;i++)
        if (number%i==0)
        return false;
    return true;
}因为无论如何都有比自己小的公因数

B1008

学习:移动数组除了b[(i+m)%n]=ve[i];用数组记录移动后
另一种想法:
数组长度为n 把数组循环右移n位(如果m>n则m=m%n)只要将整个数组a倒置 将m位倒置 再将n-m位倒置 但是要注意的是用的reverse函数改变自身

B1009

注意:此题说明了pat自带了ctrl+z可以结束循环
学习: 此种方法也可以获得倒序的效果

cout<<st.top();
        st.pop();

B1010

错误原因:完完全全理解错零多项式的题意
零多项式是指只输入10 0也就是10这个常数 得到0 0
而我理解的是输入0 0得到0 0
正确答案:

int flag = 0;
while(scanf("%d %d",&a,&b)!=EOF){
	if(b!=0){
		if(flag == 0)printf("%d",a*b);
		else printf(" %d",a*b);
		printf(" %d",b-1);
		flag = 1;
	}
}//一开始输出常数项 不只是有常数项时 利用第5题第一项没空格
if(flag==0)printf("0 0");

B1011

错误原因:没有写返回类型
改进:for循环可以合并

B1012

改进:答案和我用的都是可变数组 但是如果需要存储的变量类型一样还是用vector v[5] 方便输出控制

B1013

错误原因:一开始只让每排第10个换行 忘记还要输出 但是测试点4还是有问题 把素数表10000个的范围放大到1000000就对了 也就是每次注意程序能输出临界值

B1014

错误原因:除了字母范围的错
if(pos<10)cout<<":0"; cout<改为

printf("%02d:%02d",m,pos); 就正确了 
pat里除了空格问题 输出格式不一样也会报答案错误 
输出时钟这一类型最好使用%2d

B1015

错误原因:超时 有两个原因
1.最好用scanfprintf获得输入节约时间
2.sort尽可能往循环外放 也容易超时
改进:跟B1012一样 存储的变量一致时最好还是用vector v[5]

B1016

错误原因:部分正确 一开始用字符进行加减让位数一样多 非常麻烦 而且不知道哪里会出错 但是这题可以通过sum记录位数 通过pa=10*pa+Da;计算出66 333这样的值

B1017

错误原因:测试点1的问题 只考虑了被除数大于1位 没考虑被除数只有一位 3/7 应该得到 0 3【一开始的代码只能输出3】

B1018

错误原因:C字母小写 解不唯一输出字母序最小的解【边界】
改进:不用记录平局 并且合并for循环以后就不用加vector

B1019

错误原因:
1.2222-2222输出应该是0000写成了0
2.printf("%04d - %04d = %04d\n",z,y,n);
必须按格式输出同B1014
改进:很多地方可以合起来
学习:s.insert(0,4-s.length(),'0')一个字符串补成想要的位数

B1020

错误原因:
1.直接把范围设为20 应该是变量
2.输出最大收益应该在循环外

B1021

学习:还可以用set 的insert配合vector的count

B1022

错误原因:运行时错误 z[30]改为z[31] 两个范围(≤2​30​​ −1)加起来应该<2​3​​1【其他都正确 只有一个测试点答案错误 一般都是范围错】
学习:这也就是如何求进制

do{
        z[num++]=y%d;
        y=y/d;
    }while(y!=0);

B1023

错误原因: while(sum1<=mp[i])改为 while(sum1【跟上题一样 只有一个测试点错 是范围的问题】
改进:循环最好往if else外放 会节省时间

B1024

错误原因:依旧是未考虑到边界条件:该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999 存储长度要是9999也就意味着必须要用字符串而不能用整型保存

B1025

不会原因:
reverse好像不能反转自定义类型
结点地址/整数数据/下一结点的地址 必须找个标记
注意:
1.依旧是B1014和B1019的%04d这样的输出格式
2.这一题的测试点6 考虑不是所有点都是有用的 要加计数器
学习:

if(beginad!=-1)连接链表
     { a[sum++]=beginad;
            beginad=next[beginad];}

B1026

错误原因:B1014,B1019,B1025 同样的问题%04d输出格式

B1027

错误原因:
1.测试点10个也要输出
2.测试点3 跟B1020同样的问题 把行设成5行 导致输出剩下的很多 应该设置为变量

B1028

错误原因:
1.段错误以及可能因为比较太多次而超时
2.测试点3 要注意如果都不符合条件 只输出0
学习:直接用日期比较 不用按年月日比

if(date>="1814/09/06"&&date<="2014/09/06")

B1029

错误原因:
1.去重会调整输出顺序
学习:ant.npos表示在该字符串内不存在

 if((str2.find(str1[i])==str2.npos)
 &&(ans.find(str1[i])==ans.npos))字符串中是否存在某个字符

B1030

错误原因:
1.没有好好读题 选择尽可能多的数构成一个完美数列目的是为了让数字更多 而不是计算在最小值*p范围内的数的个数 这一题碰巧对了只是因为在范围内的个数密度比较高
2.必须要用long long 但是我感觉没有超过int的109的范围
3.超时

for(int k=i+ans;k<n; k++)
        {
            if(ve[i]*p>=ve[k])
            {
                if(k-i+1>=ans)
                    ans=k-i+1;
            }
        }
↑不超时 标记上次循环最长时间 不用从头再来
for(int k=i; k<n; k++)
    {
        if(ve[i]*p>=ve[k])
        {
            if(k-i+1>=temp)
                temp=k-i+1;
        }
    }

B1031

改进:依旧是合并for循环 以及用数组代替map键值对太麻烦

B1032

改进:跟B1025一样要找一个做标记
此题 id利用mp或者数组对应grade
B1025是结点地址利用数组对应数据和下一地址

cin>>id>>grade;
mp[id]+=grade;

B1033

错误原因:测试点2需要注意可能没有坏的键
学习: 看答案好像上档键只包括+

//上档键如果存在,则str2里的所有字符不能输出大写
//如果有大写字母,则str2里的字符不能输出大写,小写
↓换一种思维方式
//如果str1存在大写字母和str2上档键就不输出此时的str2
//如果str1有大写字母则不能输出str2
if(bad.find(toupper(should[i]))!=bad.npos)
            continue;
if(isupper(should[i])&&bad.find('+')!=bad.npos)
            continue;

B1034

错误原因:int改为longlong就对了 但是会运行超时
改进:这一题写的代码确实 写的太长
学习:
1.int longlong需要注意
2.公约数

long long gcd(long long t1, long long t2) {
    return t2 == 0 ? t1 : gcd(t2, t1 % t2);}

3… bool flag = ((m < 0 && n > 0) || (m > 0 && n < 0));异号不要用乘积判断 容易超出longlong范围
4. printf("%s", flag ? "(-" : "");尝试多使用

B1035

只会实现插入排序 测试点0.2.4为插入排序
做的非常巧的归并排序

 int flag=1,k=1;
        while(flag)
        {
            flag=0;
            for(int i=0;i<n;i++)
                {
                if(v1[i]!=v2[i])
                flag=1;
                }
                k=k*2;
            for(int i=0;i<n/k;i++)
                sort(v1.begin()+i*k,v1.begin()+(i+1)*k);
            sort(v1.begin()+n/k*k,v1.end());
        }

B1036

错误原因:
1.我以为每行中间空了一行
2.除数或者被除数中有浮点数才能得到浮点数7/2.0=3.5 7/3=2

B1037

学习:swap(a,b)交换a,b 以及多尝试用c=a>b?a:b;

B1038

注意:未vector ve(10)初始化个数 只能获得输入m 以后push_back(m)
学习:
1.count(ve1.begin(),ve1.end(),m);在范围小的时候方便查找 但是多了就容易超时
2. vector ve1(1000); ve1[m]++配合同map功能

B1039

错误原因:要考虑老板没卖小红没需要的极端情况

getline(cin,str2);必须按行获得输入

学习:B1033同种解法

B1040

错误原因:
1.超时 答案很巧妙 以A来计算P T 我开始的想法是以P来计算A T
2.修改后测试点4.5考点:sum的范围是long long 注意乘积过大

B1041

改进:同B1032将变量用数组进行对应 这样就不需要结构体

B1042

改进:先都转化位小写 然后再用B1032的方法进行对应

B1043

改进:
1.一开始的时候就可以用map进行字符和数字的对应 同前两题
2.多使用if(mp['P']-->0)

B1044

错误原因:
1.测试点1:截取字符串要考虑0的火星文tret是四个字符
2.如果输入是13的倍数不用输出个位数
3.测试点2,4:for循环范围写错

B1045

错误原因:
1.if判断条件错误
2.测试点2:最后要输出cout<
3.整道题理解错误1 5 2 3 4 按题意只有1 开始考虑的时候只看左右两个元素是否比它小和大 这样的话就会得到1 3的答案
学习:比较前后的数组元素顺序没变化才能证明是满足条件

B1046

改进:合并for循环

B1047

改进:同B1043

B1048

错误原因:要把两个数补成位数相同

B1049

错误原因:
1.超时 所以必须
2.得到v必须用v开始

scanf("%lf", &v);
ans+=v*i*(n + 1 - i);是对的i*(n + 1 - i)*v;就是错误的 

学习:ans+=v*i*(n + 1 - i); 左右两边分别考虑

B1050

此题看了柳神的代码
参考了

for (int i = 0; i < level; i++) {
        for (int j = i; j <= n - 1 - i && t <= N - 1; j++)
                b[i][j] = a[t++];
        for (int j = i + 1; j <= m - 2 - i && t <= N - 1; j++)
                b[j][n - 1 - i] = a[t++];
        for (int j = n - i - 1; j >= i && t <= N - 1; j--)
                b[m - 1 - i][j] = a[t++];
        for (int j = m - 2 - i; j >= i + 1 && t <= N - 1; j--)
                b[j][i] = a[t++];
    }

其他部分自己写了还是在最后一个测试点提示段错误 可能刚刚好有超过一开始设的a[200][200]的范围 所以最好设置成可动的
修改成一下才是对的

 vector<int>a(N);
vector<vector<int>>b(m,vector<int>(n));
一个含有m个元素的数组,每个元素又是一个数组,即vector<int>(n)

B1051

错误原因:要考虑阈值

就是对0.00这个点的A B的取法,
绝对值小于0.005,取到的就是0.00(四舍五入保留两位)
+0.005就是0.01-0.005就是-0.01,
所以正数是>=0.005 负数<=-0.0050.00介于两者之间

B1052

错误原因:测试点1.2:注意了a>0要求但是没注意a<=v[0].size()

B1053

正确且不需要修改

B1054

错误原因:比对小数点出问题
可以利用sscanfsprintf进行数字和字符串之间的转化

 scanf("%s",a);
        sscanf(a,"%lf",&c);
        sprintf(b,"%.2f",c);
        int flag=0;
        for(int h=0; h<strlen(a); h++)
        {
            if(a[h]!=b[h])
                flag=1;
        }

B1055

没有好的想法输出 只会排序成正常的队列
学习了柳神的排序方法 思想还是比较简单 但是不会实现

B1056

正确且无需修改

B1057

正确且无需修改

B1058

错误原因:又是一开始就带入数值 主观性太强了 再是大括号写错了地方
学习:自己用的是比较偷巧的一种做法 应该是按照格式获得输入

B1059

错误原因:超时 同B1042 B1043用数组对应

B1060

错误原因:题意是满足有 E 天骑车超过 E 英里的最大整数 E 但理解成必须刚刚好有E天

B1061

改进:边输入边记录 利用输入和数组中存储的正确答案进行比较 如果相同则加上数组中存储的分数

B1062

错误原因:
1.测试点1没考虑前面的分数可能比后面大
2.做题不仔细 1 2写错了

B1063

正确且无需修改

B1064

改进:开始想用vector的函数去重排序 用set排序且唯一

B1065

错误原因:
1.超时
2.测试点3printf("%05d", i);按格式输出

B1066

错误原因:
1.同B1066的格式错误
2.测试点蜜汁错误 决定不改了 用两层循环输出

B1067

错误原因:可能输出中有空格 所以要用getline获得输入 但是一旦通过getline获得输入 首先要用getchar()获得上一步的回车

B1068

错误原因:没有注意这个点是独一无二 以及要考虑边上的点

B1069

错误原因:中奖位置的网友已经中过奖,则跳过他顺次取下一位代码有问题
学习:

if(s1.find(ve[i])==s1.end())
                s1.insert(ve[i]);

B1070

错误原因:输出是向下取整 不能用四舍五入

B1071

错误原因:注意格式

B1072

改进:可以用数组 以及vector二维数组

B1073

只会根据B1058的计算分数
注意:错误选项指的是被错选的非正确选项以及被漏选的正确选项。

B1074

错误原因:应该是把进位y和每一位x放在一起再去判断是否第一位是0 而不是y加上被判断过的每一位x
学习:同B1010的方法

if(ve1[i]!=0||flag==1)
        {
            flag=1;
            cout<<ve1[i];
        }

B1075

错误原因:跟B1025一样可能出现无效值

B1076

学习:可以不以一行来看 按A-T这样的一小块字符串来看 一旦s[2]='T’那么取得s[0]的值

B1077

学习:可以获得每个组的最高分和最低分在最后算综合分时减

B1078

学习:通过B1084的思路想到的办法

B1079

错误原因:可能一开始就是回文数

B1080

错误原因:逻辑上应该是没有问题的 但是测试点3一直不过
PAT Basic 1080 MOOC期终成绩 C语言(测试点3)这个帖子说的情况很有可能 也就是因为hash冲突 所以有时候量级大时避免使用map 最好使用vector
看的柳神的算法 真的好简洁!!

B1081

改进:for循环合并

B1082

改进:用数组进行对应

B1083

错误原因:差值只要是非负就行

B1084

不会做原因:没有理解题目意思
看了柳神的代码

B1085

错误原因:
1.修改成这样才没有段错误

bool cmp(ph1 a,ph1 b)
{
    if(a.sumgrade!=b.sumgrade)
        return a.sumgrade>b.sumgrade;
    else if(a.ren!=b.ren)
     return a.ren<b.ren;
    else
        return a.name<b.name;
}

2学习到的一种不用构建数组的方式

for (auto it = mp1.begin(); it != mp1.end(); it++)
ve2.push_back(ph1{it->first, mp1[it->first],(int)mp[it->first]});

B1086

错误原因:200*5得1000,输出的结果是1,你是0001;

B1087

错误原因:范围是1-n而不是0-n-1

B1088

错误原因:丙不一定是整数 也可以是浮点数

B1089

柳神的想法跟我一模一样 果然又是我实现不出来

B1090

错误原因:看了柳神的代码 第一次用map > mp
并且这道题用了好多局部变量

B1091

改进:利用substr截取进行比较

B1092

改进:利用二维数组

B1093

学习:也可以用数组标记已经存放的

B1094

错误原因:范围写错了 应该是if(i+k>l)if(i+k<=l)

B1095

看了柳神的代码 改了一点就发现两个超时点
1.unordered_map m;//用map会超时
2. printf("%s %d\n", ans[j].t.c_str(), ans[j].value);//用cout会超时
综上 尽量用unordered_map以及printf,scanf进行输入输出

你可能感兴趣的:(PAT乙级)