PAT题记

1095 ☆综合性强 要点多 先将记录按车辆id和时间排序 使同一车辆的记录按时间顺序紧邻,然后遍历,找到可匹配的记录(前一记录为入紧接着后一记录出),累计该车停留时间,更新记录最长停留时间以及相应车辆id,判断其停留时段是否包含某一查询时间点(可能包含多个时间点)

注意:停留时长为每辆车累计停留时长

1109 先排序,然后依序每次取一排的人数处理enqueue(i,m),将每个人安排在此排相应位置mid+j*f

1128 以横纵坐标的和差(差需要+n 否则有负值不能作为数组下标)作为对角线散列表的关键值
散列表长度为2*n-1(对角线数)

1129 新颖解法 将数据组成结构体放入set 利用set动态排序
注意:不可直接更改set中元素值(it->cnt++; error:assignment of read-only location),需erase后重新insert

1133 链表题 尾接法

1134 需判断分母是否为0

1136 数字位数达1000,需使用string进行运算
判断是否回文串 使用reverse逆转后原串比较即可

1139 if(sex[u]*sex[t])是非零!! if(sex[u]*sex[t]>0)是大于零!!!
人数未必是散列表长度!!
输出时候要以4位数的方式输出
如果用int接收一对朋友,-0000和0000对于int来说都是0,将无法得知这个人的性别
先想清楚需要哪些信息,在录入数据时直接处理得到,而不必全部记录,后面再提取:
记录下每个人的同性朋友,不必记录每个人的所有朋友,也不必记录每个人的性别,省的每次从其所有朋友找挑选同性加入集合

1141 字符大小写转换c=tolower©/c=toupper© (cctype)
‘a’-‘A’=32
字符串大小写转换 transform(str.begin(),str.end(),str.begin(),::toupper);

1144 if(f) 不同于if(f>0) !!!

1148 20分!! 不会做!!!!
巧用-1 0 1 相加相乘判断关系
printf("%d %d",it,(++it));需分成两次printf("%d",* it);printf("%d",*++it);才能输出it先后所指元素,否则输出的都为++后的第二个元素

hash
开放地址法的增量序列的长度==散列表长
Linear Probing线性探测法 Quadratic probing平方探测法 Double Hashing双重散列法

1134 把边保存下来 遍历每条边,检查所给点集是否包含边的端点
柳婼hash法:用vector v[a]保存与a相关的边的编号。标记与所给点相关的边,对应的hash[i]=1。然后判断hash数组中每个值是否都是1

1145 探测次数等于表长,探测了表长次数未成功的需再加一次探测失败

1154 没必要dfs,把边存下来,每次赋予颜色后,检查是否每条边的两个顶点颜色都不同

并查集:并查集中压缩路径部分代码为if 不是while!!

1114 结构体运算符重载;注意n不是出现的总人数

1118 并查集中压缩路径部分代码为if 不是while!!
搞清楚总人数,然后初始化p数组使p[i]=i

图论

1013 检查某一城市时 设该城市已访问,即v[x]=1 然后dfs遍历 统计有几个连通分量
原做法:使用并查集,每次除去与待查城市相关的道路重新归并,

1034 n为通话记录数 则人数最多有2000个

1094 sort降序排序:sort(lel,lel+101,greater());
统计完毕后 一次遍历找出最大相比每次计数后都进行比较 更快

1103 pow函数返回值为浮点型 需用round函数 四舍五入 方可获得准确整值
减少剪枝(k个数的平方和小于n,则返回上层后不再使用更小数字累加,只会更小;总和已等于n 但个数少于k,不再寻找某数平方和进行累加)反而更快??
将对每一层的处理 放在函数中递归调用前后以及参数中 处理后的判断在下一层函数的开头进行

1106 需使用double scanf输入时转义符须用%f scanf("%d
%lf %lf",&n,&p,&r);
printf输出时%f %lf皆可 printf输出时最好使用%f 因为%lf在printf下是未定义的
有些系统不接受

1131 利用dfs回溯,可将一些变量设为形参 该题在输出及每次dfs前的初始化产生问题

1003 对起点各参数值的赋值很重要 因为可能起点也为终点
v[s]=1;dis[s]=0;tot[s]=res[s];num[s]=1; //缺少num[s]或tot[s] 即出现错误点

1018 难!! dijkstra + dfs
勿忘初始化邻接矩阵值全为inf!!! fill(g[0],g[0]+mn*mn,inf);
二维数组g[mn][mn]的首地址为g[0]

1030 easy Dijkstra函数中勿忘初始化距离为最大值!!

1072 m+n最大为1010,应设置数组最大长度mn为1011。同时要注意fill或memset函数参数范围(结点总数为m+n,m+n+1不大于mn)
fill(v,v+n+m+1,0);
memset(v,0,(m+n+1)*sizeof(int));

采用优先队列(priority_queue<P,vector< P >,greater< P >>q;
p.first小的在队头)时,队列中可能会有重复结点,重复结点第二次出队时,其距离非最短距离!!所以须最!先!判断是否是重复结点。

1087 我的做法(只用dijkstra):其中统计最短路径数目的方法:设置到达每个结点j的可能最短路径数pnum[j]初值为1。松弛操作时,若从u到达j的距离更短,则pnum[j]=pnum[u](有几条到达u的最短路就有几条到达j的最短路);若从u到达j的距离等于原本到达j的距离,则pnum[j]=pnum[j]+pnum[u](**此处关键,易搞错!!**到达j的路径数=原本到达j的路径数+从u到达j的路径数(即到达u的路径数))

二维数组g[mn][mn]的首地址为g[0] fill(g[0],g[0]+mn*mn,inf);
string类型 用cout输出

柳婼方法(Dijkstra+DFS):采用vector记录到达结点距离相同的不同路径的前驱,即可通过Dijkstra得到所有最短路径的路线,关键代码如下:

if(dis[u]+e[u][v]<dis[v])
{
	dis[v]=dis[u]+e[u][v];
	pre[v].clear();
	pre[v].push_back(u);
}
else if(dis[u]+e[u][v]==dis[v])
	pre[v].push_back(u);

然后从终点沿pre进行DFS,每次搜索到起点时,统计路径数目,检查更新最优路径

另外,可只用dfs,每次搜索到终点,统计路径数目,检查更新最优路径

1111 读清楚题!!不要想当然。。
Incase the shortest path is not unique, output the fastest one among the shortest paths, which is guaranteed to be unique. In case the fastest path is not unique,output the one that passes through the fewest intersections, which is
guaranteed to be unique.
同样短选更快的。同样快不是选更短的,而是选经过结点数更少的!!
使用复制粘贴后,一定要仔细改变量名!!!!

fill(arr, arr + n,val);
fill(vec.begin(), vec.end(),val);
可以直接用==判断两个vector是否相等

1043 二叉搜索树的先序序列可分为两部分,左子树部分都小于根,右子树部分都大于等于根。所以两部分邻接处元素应为,最后一个小于根的元素和第一个大于等于根的元素。
找到最后一个小于根的元素的位置j和第一个大于等于根的元素的位置i,若i-j!=1则不是二叉搜索树,反之递归检查左右子树,然后将当前根节点记录下来(后序遍历)。
该题半年前看同一题解后做过一遍,现再做仍不会。

1053 easy 邻接表存树,深搜记录符合条件的路径,路径排序后输出

1057 树状数组(不会)
使用两个multiset分别表示较大集合(从小到大排列)和较小集合(从大到小排列),插入和删除操作时进行调整,使小集合元素个数与大集合相等或比大集合多一个,则小集合中最大元素(*small.begin())即为中间小元素
设s(multiset)中元素为15,5,10,5 则s.erase(5)会删除全部的5,而s.erase(s.find(5))仅删除找到的一个。

1064 so easy 写完函数 记得调用。。

1066 AVL 同1123 勿因小失大(忘记t=new
btnode()和return)

1086 使用getline前 先getchar()或cin.ignore()吸收掉换行符
从条件中找到先序和中序序列 从而得到后序
尝试根据push pop过程建树后求解 fail

1099 使用复制粘贴,注意修改变量名!! easy

1102 使用复制粘贴,注意修改变量名。。 easy

1110 判断完全二叉树的不同思路:完全二叉树最后结点的序号(根节点为1,左子树2,右子树2+1),亦即结点最大序号,等于总结点数n。所以可通过遍历,记录最大序号,最后比较是否等于n。
错误点:有三个测试点因为相同原因不能通过。节点的id可以是两位数!!!!!

1115 so easy~ 动态建树过程中,累加相应层次的结点数,更新最大层次

1119 最后输出完 需要换行 否则全部格式错误。。。 可不必建树,见题解

1123 AVL 判断是否完全二叉树 只需一个标志记录前面结点是否断缺即可,详见代码

1127 注意自定义函数中形参的含义(结点个数还是序列末节点下标)
z型输出方法:将树从根结点开始所有结点层序遍历,保存在result二维数组中,比如:result[i]保存第i层所有结点的序列,根据当前层号的奇偶性分别从左往右、从右往左遍历输出

1130 孩子结点中没有出现的编号,即为树的根结点编号

1135 红黑树要求每个结点到各叶节点路径上经过的黑数相同,而非左右子树的黑数相同
二叉搜索树每输入一个结点值即动态的建树

给出先序\后序+中序遍历序列,未必一定要建树,可直接根据序列下标拆分左右子树进行相应递归算法,如:1138(柳婼题解)、1151、1135

1138 若直接键入vector中某元素,勿忘先对vector进行resize

1151 可直接根据先序和后序遍历序列找到两结点的lca,无需建树
使用map记录(值->下标),方便查找某值在数组中位置下标
//map[key] 若map中不包含key,会插入一个key元素,value取默认值,返回value。

1155 判断大小顶堆 可设置两个标志位 在一次遍历中 同时检查是否符合大小顶堆

1001 计算A+B的和,然后以每三位加一个”,”的格式输出。只要当前位的下标i满足(i + 1) % 3 == len %3并且i不是最后一位,就在逐位输出的时候在该位输出后的后面加上一个逗号

1082 考虑特殊情况!!!!!! 如输入的数字字符串为“0”
找到第i个之后首个不同的字符c=s[i]; while(++i<s.size()&&s[i]==c);

1009 可只保存第一组数据。当输入第二组数据的时候,一边进行运算一边保存结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值