PAT坑点、易错点合集

全局变量只能定义的时候初始化,不能在函数外赋值。

定义了全局变量后, 就不要再mian函数里定义一个同名字的变量,否则如果又出现子函数调用用到该变量,则会自动初始化为0!!!

要想在同一个solution下添加多个独立project,以及能独立运行main函数,则需要在solution的properties的 startup project 改为 current selection。

Dij算法可以求一个点到多个结点的最短距离,那个多个结点到一个结点(终点)的最短距离怎么求(有向图)?

    也可以使用Dij来求,但是建图的时候,所有边都是反向的,建好后以终点为起点,使用一次Dij求最短路径即可。

A1025:

若是以long long型读入编号, 则输出必须是%013lld, 否则会出错, 因为编号是恒定13位的。

若用字符数组读入则不会出现这个问题。

B1020:

题目中说的是正数,并未说是正整数,注意区分,是以应当以double型读入。

A1075:

只有当考生某题原来还未提交,当前提交未通过编译时,才能令该题等分为0,否则可能会覆盖之前的得分;

只有前提交是考生某题第一次获得满分的时候,完美解题数才能加1, 否则会影响排序。

A1085:

seq[i] * q 可能超10^9 所以只能用long long, 所以看到题目首先想象计算后的范围。

A1101/B1045

当答案个数为零0,第二行必须输出一个空行,即\n。

A1059

调用一个没有参数的函数时,最后的()不可以省略,如FindPrime()。

求质因子分解,输入为1时,需要特判输出。

B1003

题目说xPATx为正确,指的左右x是相等的, 不能不同。

A1078

哈希表处理冲突的公式为H(key) = (key + i * i) % Tsize!! 不要忘了 %Tsize。

此外发生冲突时,判定用平方探测法找不到位置的条件是step == Tsize ! !

证明如下:

当step = Tsize,即(key + Tsize * Tsize) % Tsize == key;

 (key + (Tsize + i) * (Tsize+ i)) % Tsize = (key + Tsize * Tsize + 2 * Tsize * i + i * i) % Tsize = (key + i * i) % Tsize,

其中i为1 ~ Tsize-1 的数。

还有一点就是判断是不是素数要有一个条件就是当n<= 1时,直接返回false。

A1060

当以字符串处理数据时,不要忘了可能会输入一些前导零,如000123,记得处理。

此题中规格化时可以将其分为两种情况。1、整数部分为零;2、整数部分不为零。这只用在去掉前导零后,就可以看出。当整数部分为零时,首位会变为‘.’,当整数非零时,首位会变为非零。

指数的获得:

 第一种情况:去掉小数点后, 每遇到零exp减一(初试为0),擦去首位;直到遇到非零或最后一位(因为有可能全为零)。

 第二种:每右移一位,exp加一,直到遇到小数点或最后一位(因为可能没有小数点)。

当这样处理后,如果length() == 0 说明该数为零。


A1039

用set容器时,默认从小到大排序,若想从大到小排序,只需在所有定义都加上greater<>

 例,set<int, greater<int> > st;

for(set<int, greater<int> >::iterator it = st[id].begin(); it != st[id].end(); it++)

             printf(" %d", *it);

 此时就是从大到小输出;

注:set的greater与priority的greater作用相反!!


A1063

若要查看set容器a、b中相同元素的个数,有两个思路:

 1、将b中的每个元素insert到a中,再看insert前后的差即可;

 2、通过a.find()依次寻找b中的每个元素,若找到则加1;

方法2优于方法1:①速度更快; ②不会改变原来的a, 如果使用方法1,那么当题目需要重复用到a时,则每次都要将a赋值到新的容器再insert,会慢很多。③此外,用方法2时函数的参数可以只是容器编号。


A1100

像这种数据范围最多不超过168的题目,可以采用打表的办法,即把所有的情况都枚举一遍,然后读入,在直接输出结果就可以。

string可以直接赋值,相当于制; string不能像字符数组那样一位一位赋值;可以用getline(cin,str)来读入一行以及行末的回车,但要注意之前的回车!

学习本题中的map<string, int> mp的初始化


A1022

当用int读入和输出书本编号时,一定要保证位数,前面不足的用0补齐。

用cin读入string时,空字符仅作为分隔符,并不会被读进去,输入流中还存在这个空字符,这点跟scanf中%s的读入很相似。

注意:如果单独把查询操作提炼成一个函数,那么一定要对参数使用引用,否则最后一组数据会超时。由此可见,字符串以及map等容器的参数传递速度较慢,如果需要作为函数的参数的话,需要尽可能加上引用。


A1032

这题最坑的是输入的首地址可能是-1, 因为题目说的是:地址是正的5位数,当为空指针时为-1!!

注意不要想当然的认为输入地址是正数, 也有可能是空指针!!

不过题目中能保证以其给出的首节点的地址开始的链表为一个词或为空,即不会遇到next 为-1 或 合法地址以外的值。


A1052

注意链表长度为0时,特判输出

A1074

给出的节点中可能存在无效结点。

A1097

PAT的OJ程序中:abs()仅包含在algorithm头文件中,若写了math.h则提交时会显示编译错误,但是在vs2010中只写math.h也能通过编译。

A1103

多次方根可以由pow()计算, 如pow(10.0, 1.0 / 3);

因为每个case的次方p是固定的, 可以提前算好可能取值的p次方,存为一个数组, 这样就不会因为重复计算而消耗时间了, 同时为了保证数组小标的一致性,在0位置也存上0;

A1091

当时用增量数组来枚举各个方向时,判断坐标是否需要访问的函数一定要先判断是否越界,再去判断是否为0或是否已访问,后者后者可能会越界,出现段错误。所以要么分两个if判断, 要么把判断越界的条件放在前面(if判断的“短路”现象)!!

A1043

二叉查找树的先序历遍序列是该二叉查找树插入序列的一种。

通过vector存储数组,可以很方便的比较!

A1107

两个有人的并查集合并时,并查集的个数要减一!!

A1098

STL里的queue是没有迭代器这个东西的,即不能历遍。

题目中说的是经过几次排序后, 所以初试序列不在比较范围!

A1034

通话记录最多一千条, 意味着不同的人最多有2000个!!

A1003

使用迪杰斯特拉算法求路径上边权或点权之“和”为第二标尺的思想是,初始时,只需将初始节点的d[]赋为0(如果有第二标尺距离,则赋为相应的值),就能保证第一次选择的节点必然是初试节点,然后就可以通过for循环更改最短距离(第二标尺距离等等),而不用先把初试节点拎出来单独处理。

此外,选择节点时,如果存在d相等的节点,选择哪个都不影响结果,因为想要的结果在维护d(第二标尺等等)时都已经改好了了,所以选择时,不用考虑d以外的参数。

A1030

使用Dij算法时,不要忘记外面的那层for循环,即挑选n次最短的结点。

无向图的邻接矩阵为对称阵!!不要忘了

因为要求尽量小的花费,所以cost[]应该初始化为INF(0x3fffffff),在开始第一重循环前,起点的cost应该置为0。

A1021

此题要求一个树状图中使得高度最高的根结点。

自己的想法是每一个结点都充当一次根结点,进行一次深度优先搜索,以获得全部的高度最高的跟结点。但是这样会有一个测试点会超时。

正确的写法是,第一次先任选一个结点,找出高度最高的所有叶结点集合A,再从A中任选一个结点当根节点进行一次DFS寻找高度最高的叶结点集合B,然后A、B的并集就是所要求的答案,证明见晴神宝典。

可以用set来存储叶结点集合:在第一次DFS时,碰到高度更高的结点时,st要先清零再加入结点;第二次DFS时,碰到更高的节点时不要清零(为了求并集),直接加入,但同时要改变最高高度的值。可以在DFS函数的参数中设置一个变量,用以指示是第几次。

A1072

备选点的编号为G1-Gm,输入时可以用%s处理:先读入,判断第一个字符是不是‘G’,如果是,则sscanf(s + 1...)读入,否则sscanf(s...)读入。

题目中的意思是备选点及其路径是存在的。

晴神做法是先求出所有最短距离,在同一求最大的最短距离和平均距离,这样就只用处理1-n(即居民住所)的结点数据。

而我的做法是在Dij的过程中就求最大的最短距离和平均距离,所以麻烦很多, 在统计平均距离啊, 选择最大的最短距离时啊,以及距离是否超限时啊,都要考虑是不是该把备选点的加进去!!!

A1105螺旋矩阵

螺旋矩阵为m*n,且要求m*n == N, m>=n,m - n 最小。怎么求m,n呢?

m和n必须是N的约数,又m>=n,所以m必须是不小于根号N的最小整数,因此让m从根号N(向上取整)开始不断递增,知道N%m==0为止。

一般来说二维数组[10000][10000]会容易爆内存,但是这题比较简单,只有一个大数组,也没有递归之类的,所以几乎刚好可以用。

向上取整为ceil()函数,向下为floor()。

A1017

题目没说处理时间是正整数,就有可能是0!!

A1014

一定要读清题意,题中说的是 who cannot be served before 17:00, you must output "Sorry" instead.

即17:00前被服务的都可以,之后(含)都不可以。而不是指17:00前完成的才可以。

A1026

这题难就难在分类,排队的分VIP和非VIP两种,球桌也分VIP和非VIP两种。如果排队的和服务的都是一种,按之前的做法依次来就好了,这里有两种就要详细分类了。

当接下来先来的是非VIP成员时:

        则查看最先结束的球桌:若该球桌是非VIP,则不用管结束时间是否早于该非VIP成员的到达时间,就可以直接分配;若该球桌是VIP,则看最先到达的VIP成员到达时间是否早于该球桌结束时间,如果早于,则把该球桌分配给VIP成员,否则分配给该非VIP成员。

 当接下来先来的的是VIP成员时:

        看最先结束的球桌:若是VIP桌,则直接分配,若是非VIP桌,则查看该成员到达时刻是否有VIP桌空闲,若没有,则分配非VIP,若有则分配VIP桌。

A1045

以最长不降序子序列求该题时,可以在读入是将不想要的颜色直接剔除,剩下的就可以按最长不降序子序列求就好了。

A1109

10000个人拍照,最多十排, 设置排好队的数组是,一定要开成[11][10010]!!

不要下意识地开成10000/10。

所以要注意,patOJ的时候超限也有可能显示答案错误。

A1114

有时题目给的初试条件建立的图不是连通的,所以在输入时,要注意手动将其路径变为双向的。

A1116

打卡求素数表时,当当前数为素数时,要从j=i + i 开始变为非素数,否则如果j = i开始变为非素数的话,所有的数都会变为非素数。

A1117

并查集合并的时候,一定要根节点和根节点合并,否则至合并单个节点没有意义。

A1119

next_permutation(a,a + i)超过最后一个时返回false, 一般配合dowhile。

lower_bound(a,a + i, v)和upper_bound()只能用在有序序列!!

已知一个先序和一个后序,如果该二叉树没有单孩结点时,其中序也是唯一的!!

比如

1 2 3 4 6 7 5
2 6 7 4 5 3 1

否则就是不唯一的。

怎么判断呢? 可以利用递归。因为已知当前前序序列和后序序列时,判断前序的第二个结点是不是和后序的倒数第二个结点相同,如果相同,则无法判断左右子树。否则可以划分为左右子树,递归即可。

A1123

判断是否为完全二叉树的正确方法是:已知有n个结点,利用层序历遍方法去历遍。while(n--)不管是不是空节点都加入队列,当n还没减为0时出队结点的是空指针,说明不是完全二叉树。

不完全正确的方法:不管是不是空节点都加入队列,当出队为空节点时,查看队列中是否有非空节点,若有则不是完全树。  这个方法能判定是不是完全二叉树,但是不能形成层序历遍的序列,因为可能空指针右侧的非空指针还存在子节点,而这个子节点还没有入队,自然也不会出队,所以层序少了这些节点。也就是说AVL树倒数第二层不一定全满。

A1124

对于map容器,如map<string, int> mp。 当mp["123"] 还未赋值时, 直接用if(mp["123"] == 1)去判断时, 会返回false,同时会形成mp["123"] = 0, 理解成“123”会对应一个空变量(int型时表示为0)。

set容器若想改变顺序定义的时候写成, set<int, less/greater<int> > st 即可;

而priority_queue要定义成 priority_queue<int, vector<int>, less/greater<int> > q 才行。

A1125

The result must be rounded to the nearest integer that is no greater than the maximum length.

注意理解这句话, 不要以为用一个round就是对的。 题目说的意思是取证到一个最接近的但不超过该最大长度的整数。 该最大长度就是求得的最大长度,而不是题目给出的segment最大长度。(怎么读题老是出错呢! 老是跳跃性思维!)

A1126

题目给了一个定义:对于连通图。。。

所以这一切都是建立在连通图的基础上的, 所以判断前需要判断是否为连通图!!

A1139

坑点1:题目中说id为负数代表女生,正数代表男生, 那么就要考虑-0的情况, 这时就需要按字符串读入, 而不能按%d读,否则+0 和-0无法区分。

坑点2:要以%04d输出id

坑点3:题目中说了A找B需要先找到A的好友C,再通过C的好友D来给D的好友B传话, 所以找A的子节点时要排除B,否则可能A->B->C->B,此外找C的子节点时,要排除A,否则可能A->C->A->B。

A1139

地铁图中一个点所在的线路编号可以有多个, 同一仅通过一点无法确定地铁线路,

此时应该想到用两个点可以唯一确定,所以只需建立一个G[][],表示两个点之间的地铁线路号。

A1135

任意一个二叉排序树的先序序列Pre[] 与 该二叉排序树的插入序列相等

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值