首页 > 编程知识 正文

pat题库及答案,c程序设计实训心得

时间:2023-05-05 04:49:52 阅读:14816 作者:1285

首先,我要开始说最重要的心得。

写代码之前,先写在纸上画画,写伪代码,整理思路,上来不敲代码,效率极低,也容易出错误。

从2019-12-12到2020-01-17,在c上完成PAT乙级95题,第682个进入满分行列。

主题链接:

PAT乙级真题

为每个问题创建了相应的CSDN博客:

张35的CSDN个人主页

代码已上传到Github :

PAT-Basic-Level.git

每五题一套,分数为15、20、20、20、25,相当于PAT乙级考试一次。 主题一般都不难。 因为乙级不考察数据结构,所以我觉得乙级的问题几乎等于算法分析中的伪代码。

有些主题很麻烦,测试点很难通过,但多亏了被惯坏了的鼠标代码,才有参考价值。 她的代码风格简洁规范,博客有序,在STL库的运用上更熟练。 被惯坏了的鼠标博客:

柳婼的博客

柳婼的CSDN个人主页

之后,每次做题的时候,不管对错,都会寻找被惯坏的鼠标代码,看有没有不能优化的地方。 我写的可能比被惯坏了的老鼠更容易:

PAT乙级真题1087实现了多少不同的值c (求公式,一行代码即可) )。

困难和代表性如下:

PAT乙级真题1025逆转链表

PAT乙级真题1034有理数四则运算c的实现(两个int相乘的结果,应用长长内存) ) ) ) ) ) ) ) ) 652 )

PAT乙级真题1035插入与合并

PAT级真题1040有几种PAT C的实现

PAT乙级真题1045快速排序c的实现

PAT乙级真题1050螺旋矩阵c的实现

PAT乙级真题1070结绳c的实现(如需求哈夫曼树) ) ) ) ) ) ) ) ) )。

PAT乙级真题1089狼人杀-简单版c实现(假设用遍历暴力解决) ) ) )。

遇到上帝的漏洞也解决不了的有以下几个。

PAT乙级真题1030完美数列c的实现(测试点4超时神坑) ) ) ) ) ) ) ) ) ) ) )。

PAT乙级真题1035的插入和合并c的实现(要求解答)测试点4浮点错误,但不知道为什么得了满分() ) ) ) ) ) ) ) ) )。

一开始基本上每天坚持一条路线,越往后擦得越快。 最多的日子是2020-01-14,刷了9个疗程。 收获是熟悉网上刷问题的一般途径和C STL库的使用方法。 总结一般操作和技巧。

常用函数isprime (# includecmathboolisprime (intn )//pow ) n,0.5 )超时,sqrt效率大幅提高for ) intI=2; I=sqrt(n; I ) if(n%I==0) {返回假; } }返回真; } isNumber ()在sstream中判断字符串是否为数字

# includesstreamboolisnumber (strings ) istringstreamsin ) s; 双测试; return sin test sin.eof (; }swap(c标准命名空间中有交换函数。

STD:3360swap(ta,T b );

可以直接用于各种类型。

常用的STL库操作是在vector中对sort进行排序(v.begin )、v.end )、cmp );

通过set判断兼容性的set的一般使用方法如下。

#包含集使用名称空间STD; 插入定义setint myset的//元素myset.insert(20 ); //搜索元素set int :3360 iterator it=myset.find (20; //检查某个值if是否不存在(myset.find(value )==myset.end ) )…}//删除元素myset.erase (it ); //删除所有元素myset.clear (; //set判断是否为空if (myset.empty )……) set为红黑树形结构,基本平衡,插入、删除、检索操作的时间复杂度均为o ) O(logn,可以自动排序。

适用性问题判断: PAT乙级真题1064好友数

map认为只有mapint可用,int计数出现的数字,在阅读某个值时直接:

图mapp[v[i][j]];

map使用[]索引值,如果key不存在,则添加该key,并调用value的默认值作为该值。 int的默认值为0。 所以可以使用地图直接计数。

遍历映射遍历映射语法如下:

//show content : for (STD :3360 map char,int :3360 iterator it=mymap.begin ); it!=mymap.end (; it ) std:cout it-first '=

> " << it->second << 'n'; 反向遍历

以map为例,反向遍历STL库容器:

for (map<int, int>::reverse_iterator rit = countMap.rbegin(); rit!=countMap.rend(); ++rit){ cout << rit->first << " " << rit->second << endl;}

类型map<int, int>::reverse_iterator可以换成auto(C++11特性)。

输入输出 用getline读带空格的一行字符串

读取一行带空格的字符串,需要用getline(cin, s);

cin >> s只能读到空格前一个单词。

用scanf读string

用scanf替代cin时,无法直接读入string类型,可以先读进一个临时字符数组里,再把字符串数组赋值给字符串即可,如:

char temp[10]; scanf("%s", temp); string str = temp; 打印定长数字

1、cout:

#include <iomanip>cout << setw(5) << setfill('0') << i;

2、printf:

printf("%05d", i); 小数点后精确2位

1、cout:

#include <iomanip>cout << fixed << setprecision(2) << i;

2、printf:

printf("%05d", i); printf打印百分号%

用printf输出’%’,加转义字符’%'是不对的,正确做法是:

printf("%%");

字符串处理 使用cctype.h判断字符类型

使用c++中”cctype”(c中的“ctype.h”)能极大提高效率,包括对单个字符判断类型及大小写转换的函数:

isalnum() 如果参数是字母数字,即字母或数字,该函数返回trueisalpha() 如果参数是字母,该函数返回真isblank() 如果参数是空格或水平制表符,该函数返回trueiscntrl() 如果参数是控制字符,该函数返回trueisdigit() 如果参数是数字(0~9),该函数返回trueisgraph() 如果参数是除空格之外的打印字符,该函数返回trueislower() 如果参数是小写字母,该函数返回trueisprint() 如果参数是打印字符(包括空格),该函数返回trueispunct() 如果参数是标点符号,该函数返回trueisspace() 如果参数是标准空白字符,如空格、进纸、换行符、回车、水平制表符或者垂直制表符,该函数返回trueisupper() 如果参数是大写字母,该函数返回trueisxdigit() 如果参数是十六进制的数字,即0~9、a~f、A~F,该函数返回true tolower() 如果参数是大写字符,则返回其小写,否则返回该参数toupper() 如果参数是小写字母,则返回其大写,否则返回该参数 reverse()

倒置字符串,用法为:

#include <algorithm>std::reverse(myvector.begin(),myvector.end()); 提高效率 遍历一遍同时得到最大、最小值

用两组临时变量,记录最大、最小两组值,如果有新的最大/小产生,相应更新改组数据。

如: PAT乙级真题 1004 成绩排名 C++实现

cin、cout与scanf、printf

cin、cout比scanf、printf慢很多,但只需在main函数第一行加上:

std::ios::sync_with_stdio(false);

就能快很多。因为C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑到了一起。这行代码的作用便是取消iostream与stdio的默认关联同步,取消同步后的iostream的性能倍增,能与stdio相差无几。只要注意不要再混用iosteam和stdio即可,否则可能会出现预料之外的错误。

还能进一步提升效率,还可以再加上:

std::cin.tie(0);

但PAT乙级真题 1095中添加ios::sync_with_stdio(false); 和cin.tie(0);依然超时,改成scanf、printf后就AC了。

str = str + "a"与str += "a"效率差距很大

前者产生了新的对象,再把结果返回;后者只涉及到对象的引用,不产生新对象。

拼接字符串最好使用str += "a" ,效率较高。

pow(n, 0.5)换成sqrt(n)

开方用pow(n, 0.5)有时会超时,sqrt效率大增。

排序传参使用引用传参

娇气的鼠标说:“排序传参建议用引用传参,这样更快,虽然有时候不用引用传参也能通过,但还是尽量用,养成好习惯”。
代码如下:

bool cmp(const Info &i1, const Info &i2){ return i1.score==i2.score ? i1.s<i2.s : i1.score>i2.score;} 用vector代替map

索引是数字的时候,可以用vector代替map,用空间换时间。毕竟限定时间宝贵,空间几乎无限。

用unordered_map代替map

map是用红黑树实现的,默认按key排序,使用unordered_map即不排序的map,能提高不少效率。

重要扩展知识 数值有效范围 char -128 ~ +127 (1 Byte) short -32767 ~ + 32768 (2 Bytes) 3*10^4unsigned short 0 ~ 65536 (2 Bytes) 6*10^4int -2147483648 ~ +2147483647 (4 Bytes) 2*10^9unsigned int 0 ~ 4294967295 (4 Bytes) 4*10^9long == intlong long -9223372036854775808 ~ +9223372036854775807 (8 Bytes) 9*10^18double 1.7 * 10^308 (8 Bytes) 位运算符

运算符有4种:
&(按位与)、|(按位或)、^(按位异或)、~ (按位取反)。

可以用异或判断异号

//a,b异号或者有一个0直接算。 if ((int)(a^b)<0) { …… }

异或运算符是“相异”为1,“相同”为0:

若x^y>0 则二者同号(符号位为0)若x^y<0 则二者异号(符号位为1)

如:
1 ^ 1 = 0 ^ 0 = 0
1 ^ 0 = 0 ^ 1 = 1
(这里的1和0是位,不是数值)

再例如,1 ^ -1 = -2。因为数据在内存中以补码表示(以8位为例):
1 = 00000001 --> 00000001(补码)
-1 = 10000001 --> 111111111(补码)
异或是在补码的基础上运算的,二者异或结果为11111110(补码)–>10000010 = -2。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。