前言
大学期间项目做了不少,而在算法题方面还是个小白。借着考研机会,把PAT甲级刷一遍,同时记录一下心得。主要参考的是柳神的题解,略过了不会考或考的可能性很小的题。
1012 The Best Rank (25)
思路
设置结构体存储成绩,分别排序计算排名就行啦。
小技巧
- 设置一个exist[]数组,用于快速定位特定id结构体的下标。
- 通过设置一个全局变量flag,减少cmp()函数的重写次数。(好久没写忘了这个技巧,结果傻傻写了四遍)
踩过的坑
- 要注意平均成绩是四舍五入的。(虽然没有四舍五入也过了,但今后也要注意)
- 第一次写的时候,错误地在sort排序前设置了exist[]的值(实际应该在排序后再设置),导致最后寻找id的对应下标失败。
链接
1025 PAT Ranking (25)
思路
先局部排序,后整体排序。
小技巧
- 多练练STL
踩过的坑
- 最后一个测试点过不了,一查发现是id的原因。题目说明id是13位的数字,最后输出时一定要补齐前缀0.
链接
1028 List Sorting (25)
思路
做了前面几题就感觉挺简单的,注意一下输出id补齐前缀0就行。
链接
1055 The World’s Richest (25)
思路
这是道过去没做出来的题,其实不用想得过于复杂,在按照财富值排序结束后直接依据年龄判断是否输出就能AC。柳神的解法对于这道题来说其实复杂化了,但还是非常值得学习。下面贴一下我AC的代码。
小技巧
- 使用数组存储每个年龄段前100的富人。(本题可不用考虑)
踩过的坑
- 之前没做出来是因为思考太复杂,虽然通过了样例但肯定没有考虑到所有情况。其实这道题不需要想太多也能解出来。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct Wealth{
char name[10];
int age;
int money;
}wea[100010];
bool cmp(Wealth a, Wealth b){
if(a.money!=b.money) return a.money>b.money;
else if(a.age!=b.age) return a.age<b.age;
else return strcmp(a.name, b.name)<0;
}
int main(){
int N, K, maxnum, minage, maxage, j, cnt;
scanf("%d %d", &N, &K);
for(int i=0; i<N; i++) scanf("%s %d %d", wea[i].name, &wea[i].age, &wea[i].money);
sort(wea, wea+N, cmp);
for(int i=0; i<K; i++){
cnt = 0;
scanf("%d %d %d", &maxnum, &minage, &maxage);
printf("Case #%d:\n", i+1);
for(j=0; j<N; j++){
if(cnt==maxnum) break;
if(wea[j].age<minage||wea[j].age>maxage) continue;
printf("%s %d %d\n", wea[j].name, wea[j].age, wea[j].money);
cnt++;
}
if(cnt==0) printf("None\n");
}
return 0;
}
链接
1062 Talent and Virtue (25)
思路
想到给结构体加上一个"type"类型,cmp函数优先根据type来判断前后关系,就很容易了。柳神开了四个数组分别存储四种类型,也是一种新思路吧。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int N, L, H, i, cnt=0;
struct Stu{
int id, talent, virtue, type;
}stu[100010];
bool cmp(Stu a, Stu b){
if(a.type!=b.type) return a.type<b.type;
else if((a.talent+a.virtue)!=(b.talent+b.virtue)) return (a.talent+a.virtue)>(b.talent+b.virtue);
else if(a.virtue!=b.virtue) return a.virtue>b.virtue;
else return a.id<b.id;
}
int main(){
scanf("%d %d %d", &N, &L, &H);
for(i=0; i<N; i++){
scanf("%d %d %d", &stu[i].id, &stu[i].virtue, &stu[i].talent);
if(stu[i].virtue<L||stu[i].talent<L){
stu[i].type = 5;
continue;
}
else if(stu[i].virtue>=H&&stu[i].talent>=H) stu[i].type = 1;
else if(stu[i].virtue>=H&&stu[i].talent<H) stu[i].type = 2;
else if(stu[i].virtue<H&&stu[i].talent<H&&stu[i].virtue>=stu[i].talent) stu[i].type = 3;
else stu[i].type = 4;
cnt++;
}
sort(stu, stu+N, cmp);
printf("%d\n", cnt);
for(i=0; i<cnt; i++){
printf("%d %d %d", stu[i].id, stu[i].virtue, stu[i].talent);
if(i!=cnt-1) printf("\n");
}
return 0;
}
链接
1075 PAT Judge (25)
思路
耐下性子写其实不难,就是要注意几种边界情况。
踩过的坑
- 最后一个测试点包含了一种特殊情况:当某人第一次编译失败,第二次编译通过该题且得分为0分,最后总分也是0分,他的成绩也应输出。
链接
1080 Graduate Admission (30)
思路
这道题虽然分值高,但有了前面题目练习并把思路捋顺并不难,也刚好锻炼了使用vector的能力。不过这题需要细心,我提交了三次才过(T__T)。在牛客网上有一样的题,可以看到自己不通过的样例数据~
踩过的坑
- 注意输出要求,id要从小到大排列。
链接
原题链接
[牛客网链接]https://www.nowcoder.com/questionTerminal/9440e63bee244bcabd55b7d71ed1e667)
题解
1083 List Grades (25)
思路
刚做完1080,这道题真的挺简单哈哈哈~好像也没什么坑。
链接
1095 Cars on Campus (30)
思路
我觉得应该归为字符串处理题。。。思路很清晰,在最后查询时要利用好查询是按照时间递增这一条件,否则会出现超时。
链接
排序类型先刷到这啦,剩下的要等复试后再刷了~
剩下的排序题:1098、1101、1113、1125、1146、1153