PAT(甲级)各题错点记录

为自己二刷PAT记录错点,防止重复失误,以及提高找bug和分析问题的能力

A1008.Elevator

  1. 自己所用方法:直接方法。
  2. 错点:
    1)犯了个傻。。。一行输入了4个数就忘记前面第一个数是N了,是看分行输入看习惯了。。。结果算样例数据算了好久都不对,算不出41,这样的错误简直不要再犯了。。。
  3. 学到了:
    1)柳:一个新写法——while处的判断也用cin>>a。在前面接收N时用cin>>a(相当于这个N接收的无用),这样当没有输入时while可自动中断循环。

A1015.Reversible Primes

  1. 自己所用方法:进制转换 + 素数,常规模板处理。唯一要注意的是逆置P进制转换成十进制时写对了但有点自己把自己绕晕了:是十进制转成P进制后,低位存在z数组第一位,所以逆置就是从高位开始算,则才从后往前算,如23的二进制是10111,但z数组里存的是11101,刚好是逆序,就从后面开始算得到29。
  2. 错点:
    1)进制转换忘了。。又去看了相关部分的书才写出。
    2)第一次提交一个测试点没过,看完书发现是输入1也要判No(以后要记得bool数组p的p[1]值要设为false了),修改之后AC了。
  3. 学到了:
    1)输入1要判No
    2)可以用if-else,if判N是否为素数,若不是则直接输出No,是的话就else处理逆置的数。

A1049.Counting Ones

  1. 自己所用方法:想尝试计算1-10、11-20、21-30…91-100中各出现的1数,为21。然后从101-200则为(21-1)+100,从201-300为(21-1),…再然后1-1000中出现的1数为以上总合,1001-2000也依次计算…但做着做着不知道规范应该设在哪,觉得这个方法肯定有问题,绕来绕去(也是对自己不行非常肯定),就去看解析了。
  2. 错点:
    1)无巧妙思路。且总结归纳出的式子一开始无法理解,单步跟了一遍才懂。感觉想从一个案例总结出这样的式子,让我自己来不太可能。。。
  3. 学到了:
    1)晴:此题用把当前位now设为1并判断左右数据left、right的可取范围(要保证小于N)的方法来计算1的个数。并设置一个变量a来辅助计算各left、now、right的值。

A1059.Prime Factors(写了结果没保存,第二次做再写吧)

  1. 自己所用方法:
  2. 错点:
  3. 学到了:

A1072.Gas Station
(此题代码在思路上太不清晰不敢写)

  1. 自己所用方法:想在Dijlstra函数中作复杂处理;加油站编号通过map或数字转化实现。。?
  2. 错点:
    1)不知道怎么处理加油站编号“Gx”;
    2)题意理解有问题。以为要求“最大距离”,实际上要求的是“最大的”最短距离;
    3)最大顶点数设定有问题。只关注了房子数N是1000,但还有加油站数M为10也要考虑,因此maxn不能只设为1010,而应为1020;
    4)照敲代码时memset函数忘记加头文件cstring,OJ出现“编译错误”。
  3. 学到了:
    1)解决错点1:可以通过把加油站编号加上房子总数设定一个新编号来判断(要按字符串读入);
    2)此题不用在dijkstra函数里计算其他标尺,而要在main函数里进行逻辑处理(因为要遍历d[]数组的结果);
    3)晴:注意getID函数和main函数;

A1081.Rational Sum

  1. 自己所用方法:常规地按照算法笔记上所教模板写出,但有个点要注意,自己令的Fraction型的sum存和,一开始分子为0,分母要为1!(最初写成了0,结果运算结果错误)
  2. 错点:
    1)有个很险的地方,但这题不知为啥没判我错,就是输出判断是假分数时要用abs(r.up) > r.down,而我只写成了r.up > r.down,这次是没栽跟头,以后要注意!!!
  3. 学到了:
    1)之前照书上打代码时要注意的点基本上都在这题里了,还好都记得,都写对了,比如add函数return时要先约分,要return reduction(result),还有reduction化简函数里不同的if-else、输出函数里不同的if-else,熟练掌握记得就好。

A1087.All Roads Lead to Rome

  1. 自己所用方法:用Dijkstra+DFS,Dijkstra中算了边权和点权,DFS中算最短路径条数、平均点权和具体路径。用一个map映射字符串和整数,最后输出时用遍历这个map的方法找到整数对应的字符串。
  2. 错点:
    1)第二个测试点没通过,但不打算深究了,3分;
    2)过程中的bug:DFS中传参pre[v][i]写成了pre[v];题目要记得结合样例中数据,平均点权不包括起点!;string要用cin和cout输入输出!;改代码时[ ]( )误删!。
  3. 学到了:
    1)晴:用两个map来分别对应字符串与整数的映射、整数与字符串的映射;且直接在输入时用i作顶点编号( i 从1到N - 1);
    2)日:用unordered_map存字符串和整数的映射,用string数组来进行整数和字符串的映射!

A1088.Rational Arithmetic

  1. 自己所用方法:也是常规按书上模板打就行了。(很畅快,加油!)
  2. 错点:
    与A1081一起写的,两道题共同有过的bug是:①reduction函数忘记retuen result了,不过这是代码错误编译器会提醒还好;
    ②输出函数里判断假分数时A1081问题是abs(r.up) > r.down,此题是判断时记得abs了,但输出去整后的分子时又忘记要abs(r.up) % r.down。。总之一定要记得判断假分数时分子要取绝对值啊!
  3. 学到了:
    1)晴:①特判除法的除数为0时只要判断b.up == 0就好了。②判断是否输出括号,只要在输出的开头和结尾两次判断r.up < 0,小于0输出。
    2)柳:①通过判断分子分母相乘,若m * n == 0,则用条件表达式判断是否是分母为0来输出Inf或0:printf("%s",n == 0 ? "Inf" : "0");;②通过分子分母异号情况得到flag值,来判断是否需要输出括号:bool flag = ((m < 0 && n > 0) || (m > 0 && n < 0));printf("%s", flag ? "(-" : "");等。

A1096.Consecutive Factors

  1. 自己所用方法:先入为主求质因子求素数表,结果题意完全理解错,牛头不对马嘴。
  2. 错点:
    1)题意未理解。只是要分解因子,不一定是质因子(你看样例里还有6!还有6!还有6!)
    2)二刷完全忘记如何求质因子,我哭了
  3. 学到了:
    1)晴:只需记录两个点,第一个连续整数的值ansI,连续整数的长度ansLen。通过for循环遍历2到根号N,再通过while(1)循环判断能否整除。

A1100.Mars Numbers

  1. 自己所用方法:进制转换,读一个转一个,且细节处理不好,方法有问题
  2. 错点:还是题目没看懂。13是tam那里,没有get到它是十位为13的倍数、个位为0的情况
  3. 学到了:
    1)柳:stoi(s)直接把string类型s转换为int型;substr的第二个参数是子串长度;不是通过进制转换,而是通过if(t/13)来判断是否是有高位的数,还有在取子串时,无论怎样都先取前3个,判断总串的长度,如果大于3就说明有第二个,也就是低位,取得后如果if (s1 == a[j] || s2 == a[j]),就t2 = j, t1和t2分别对应高位和低位,无论s1和s2哪个被赋值,都是t2低位先等于j。
    2)晴:打表,分情况把数字全部存到两个数组中,一个string数组一个map数组,分别对应10到13、13到10;更高位的那些东西是13的倍数

**A1101.Quick Sort **

  1. 自己所用方法:没写
  2. 错点:用柳/晴的方法都写了一遍,对晴的方法,令了一个bool型isPivot数组来判定是否为主元,但是这样不可取,因为题目中数的大小不超过10的9次方,数组无法开这么大,所以只能用一个ans数组来存主元结果。
  3. 学到了:
    这一题和快速排序没关系,只是应用了它的背景,重点在于转换思维,题目意思就是说要求一个数,左边的数都比它小,右边的数都比它大,作为主元。
    1)柳:对输入序列进行排序,能做主元的数在序列中的位置一定不会变化,再判断其左边的数的最大值是否比它小,就行了;
    2)晴:设定两个数组leftMax[]rightMin[],先令leftMax[0] = 0rightMin[N - 1] = INF,随后依次根据每个a[i - 1]a[i + 1]的值来最终求得两个数组的所有值,再判断每个a[i]与两个数组对应位置的大小即可。

A1103.Integer Factorization

  1. 自己所用方法:无
  2. 错点:没有思路;用柳的方法,tempAns不能用push_back而要用下标赋值,这样递归回来之后才能覆盖深层递归的值。且在调用DFS之前在main函数里要用tempAns.resize(K)设定tempAns大小,才可赋值。
  3. 学到了:
    1)柳:vector数组用下标赋值,DFS设定4个参数:i、tempK、tempSum、facSum,在DFS里面用while循环遍历;用pow(index,P)函数在一个vector数组先存放从1~N所有数的K次方值,随后DFS遍历选值。遍历用i的值不断–,减到1时return(因为i为0时不需要选)
    2)晴:其余都相同,不同的是在DFS里面,用选/不选分支来走两条不同的DFS路。

A1104.Sum of Number Segments

  1. 自己所用方法:暴力枚举方法。
  2. 错点:
    1)找规律,没找出来。。。
    2)后两个测试点超时。
  3. 学到了:
    1)晴:多举几个例子,观察长度为n的序列中各个数出现的次数,则发现是i * (N + 1 - i)
    2)柳:看序列首尾指针,假设当前数为i,首指针范围是1 ~ i,尾指针范围为i ~ N,则次数i * (N - i + 1)

A1106.Lowest Price in Supply Chain

  1. 自己所用方法:BFS,层序遍历,判断结点价钱大小并计算个数
  2. 错点:
    1)队列的类型应该设为int而不是node
  3. 学到了:
    1):晴:在main中先令r等于r/100,随后用DFS,用p*pow(1 + r,depth)来计算叶子结点的权值,并且DFS参数为index和depth
    2):柳:同上,另外的为,DFS主要用来求minDepth即最小深度,只要大于最小深度就return,并且通过判断叶子结点之后判断是否为最小深度

A1107.Social Clusters

  1. 自己所用方法:二刷,记得令爱好数组存第一个有此爱好的人编号
  2. 错点:后续有相同爱好的人,令father[i] = hobby[id],是错的,因为只合并了它自己一个人,而不是它所在的整个集合
  3. 学到了:晴、柳——并查集合并一定要用Union!

模板:

  1. 自己所用方法:
  2. 错点:
  3. 学到了:

你可能感兴趣的:(算法)