知识点
输入输出
-
gets() puts()
PAT中不能使用puts()、gets(),可以用以下代码替换char a[100]; fgets(a, 100, stdin); //遇回车后停止输入,输入的最后一个字符为'\r' fputs(a, stdout);
-
cin与cout
#include<iostream> #include<iomanip>//在控制精度时 using namespace std; int main(){ int n; double db; char c; char str[10]; cin>>n>>db>>c>>str; cin.getline(str,10);//整行读入 string str; getline(cin,str); cout<<n<<" "<<db<<endl;//endl表示end line //精度输出 cout<<setiosflags(ios::fixed)<<setprecision(2)<<123.456<<endl; }
-
scanf()与gets输入字符串
使用scanf("%s",str);
读取字符串时,以空白符(空格、Tab)和换行为截至标志,如果有空格,只能读取空格前的一段字符串。
scanf使用%c会将空格和回车读入,可以使用getchar()在之前吸收空格。
使用fgets(str,maxn,stdin)
读取字符串时,以换行符作为截至标志,最后一个为’\r’.在使用scanf读取数据后,使用gets,需要在scanf之后加上getchar()吸收回车。
cin读入字符串是以空格和换行结束的,读入一行使用getline(cin,str);
-
用户给定长度的数组
//错误范例 int n; scanf("%d",&n); int a[n]; // //正确范例 const int N=100000; int main(){ int n; int a[N]; scanf("%d",&n); }
-
输入到文件末尾
EOF表示-1,while(scanf("%d",&a) != EOF ){ }
直到文件末尾 -
char[]进行修改
注意当修改后的长度小于之前的长时,应当最后一位置‘\0’
数据类型
-
赋初值
如bool bool right[130]={true};是不行的,需要使用fill函数: fill(right,right+130,true);
-
char型变量大小写互换
小写转化为大写c-=32;
或c=c-('a'-'A');
大写转化为小写c+=32;
或c=c+'a'-'A';
-
long long与int
当题目给出范围[-231 ,231]时(int的数据范围是[-231,231-1]),需要使long long类型,输入输出使用"%lld"。(数据范围[0,1010]同理) -
long long数据计算溢出
long long的范围[-263,263-1],两个两个整数相加会溢出。
1.正溢出:A+B的最大值为264-2,long long存储正溢出之后的区间在[-263,-2](由(264-2)%264=2可得右边界)。当A>0,B>0,A+B<0为正溢出。
2.负溢出:A+B的小大值为-264,long long存储负溢出之后的区间在[0,263-1](由264%264=0可得左边界)。当A<0,B<0,A+B>=0为负溢出。
3.A+B不能直接在if中,必须先存储在long long类型变量 -
浮点数的比较
const double eps = 1e-8; #define Epu(a,b) ((fabs((a)-(b)))<(eps)) //(==) #define More(a,b) (((a)-(b))>(eps)) //(>) #define Less(a,b) (((a)-(b))<(-eps)) //(<) #define MoreEqu(a,b) (((a)-(b))>(-eps)) //(>=) #define LessEpu(a,b) (((a)-(b))<(eps)) //(<=)
文件读取
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char data[100];
ofstream outfile;//输出文件流,创建文件,并向文件读取信息
outfile.open("data.txt");// 以写模式打开文件
cin.getline(data, 100);
outfile << data << endl;// 向文件写入用户输入的数据
cin.ignore();
outfile.close();// 关闭打开的文件
ifstream infile; //输入文件流,从文件读取信息
infile.open("data.txt"); // 以读模式打开文件
infile >> data;
// 在屏幕上写入数据
cout << data << endl;
infile.close();// 关闭打开的文件
return 0;
}
日期计算
while(a.dd<b.dd||a.hh<b.hh||a.mm<b.mm){
a.mm++;
if(a.mm==60){
a.hh++;a.mm=0;
}
if(a.hh==24){
a.dd++;a.hh=0;
}
}
注意
- 在for循环时,把循环条件写为
i<strlen(str)
不是好习惯,strlen函数本身内部实现是要时间。 - 使用hash数组方法时,注意数组有界。
刷题记录
- B1008.数组元素循环右移问题
题目没有给定M的最大值,不能认为M<N,因此读入M、N之后需要 M=M%N - B1018.锤子剪刀布
手势循环相克,k1剩k2表示为(k1+1)%3==k2
手势的表示一维数组char mp[3]={'B'.'C','J'};
- A1046.最短距离(超时)
由于题设规定时间为100ms,数组最长105,查询最多104,若每次查询要遍历整个数组,需要109次操作。可以使用dis数组和sum累加,dis[i]表示从点(i-1)到点(1)的距离,dis(left,right)就是dis[right-1]-dis[left-1],时间复杂度O(1)。 - A1065.A+BandC
注意大数计算的溢出问题,以及A+B不能直接在if中,必须先存储在long long类型变量 - B1010.多项式求导
注意如何表示输入结束,关注一下《上机指南》中P24的方法和count的作用a[i-1]=a[i]*i; a[i]=0;//求导后当前系数必须清零,否则后面无法覆盖
- B1041.考试座位号
题目中机试座位号唯一,可以表示为数组下标,这样查找时可直接获取。 - A1031 U型输出
题目中看懂n1=n3=max{k|k<=n2 for all 3<=n2<=N} n1+n2+n3-2=N
的意思,同时学会使用二维数组输出图形 - B1037 零钱计算
由于涉及到负数,可以直接将所有G.S.K转换为K进行计算之后再转化回来 - A1077 求公共后缀
由于输入的字符串中会有空格,因此不能用scanf,应使用fgets(最后一个字符是’\r’,应该str[i][slen-1]='\0';
处理掉)。同时,在scanf与fgets之间使用getchar吸收换行符 。 - B1029 旧键盘
每个问题按键只输出一次,需要使用bool型数字HashTable[128]表示是否已经输出。(同时会字母大小写之间的转化) - A1048Find Coins
注意HashTable[]的越界问题。money[i]<data&&????????? - A1067 Sort with Swap(0,*)
在index[0]==0时寻找一个不在本位的数,从头枚举出现超时,应该定义一个k,记录不在本位的最小下标,每次枚举从k处开始。同时,明白index的意义,不再重复使用data[] - A1029 求两个数列中位数
使用two pointers方法是可以在每一个数列末尾添加INF=(1<<31)-1,在扫描时,防止数组越界。 - A1078 hashing
题目要求二次方探测的方式处理冲突,公式为M=(a + step*step)%TSize
当step从0~TSize-1枚举中没有找到位置,则表示插入失败(循环节为TSize)。当TSize不是素数时,重新赋值一个大于TSize的最小素数。 - A1096 被连续数乘积整除
注意当len为0时,输出的len为1,因子为n自身。在找到连续第一个数时,进入循环判断len,此时i的值不应该变化。 - A1059 质因子
注意n为1或素数时的特殊情况
注意思路
-
A1042 扑克牌(扑克牌的数组表示,next表示下一次的位置,end和start表示编号
end[next[i]]=start[i];
) -
B1048 数字加密(部分出错)
-
A1082 读数字
-
A1016 电话账单(熟悉日期计算,时间计算差值,利用hadPrint标记是否输出)
-
A1095 校园内的车(map的使用以及时间匹配,时间表示)
-
P117 n皇后问题回溯
-
P122贪心区间问题
-
A1033 油箱问题,贪心算法。
-
A1038 字符串组合为最小数,注意cmp函数的写法,string类型的应用
-
A1085 对于一个数列,查找M<=m*p的最长子数列。注意使用二分法upper_bound().
-
A1010 寻找最小进制数,使得两数相等,注意使用ll数据类型,上下界的确定,以及将多进制转化为十进制的运算,二分法应用。
-
A1044 P173 查找和大于或小于S的子数列。注意sum[]递增数列的应用,子数列[i,j]的和为sum[j]-sum[i-1]。同时注意upper_bound()的使用,以及nearS的求解。
-
A1093 有几个PAT 用数组统计A左边的P个数,统计A右边的T个数,相乘的和即为所求
-
A1049 [0,n]以内的数字的1的个数。寻找对于每一位,当取1时,可以有多少种情况,学会使用left、right、mid。(同理与数列片段和A1104求每一位上,可能的情况)对于mid=0、1、else找出规律
-
A1039 P1039学生与选课 给出每门课上的学生姓名,求每个学生所选的课。由于又一轮数据较大,使用string和map会超时,可以将姓名进行hsah求解,
M=26*26*26*10+1;
学生选择的课程编号为vector<int> course[M]
-
A1047 P235与上题类似,本题目是给出学生的选课,输出每门课的学生,使用
vector<int> course[maxc]//存放第i门课的学生编号
学生编号与学生姓名相对应char name[maxn][5]
-
A1060 P241 科学计数法string应用
-
A1022 P255 使用
map<string, set<int> > mp
;string和map传递参数较慢,尽量使用引用来调用参数;对于关键字的读入while(cin>>key){ mpKey[key].insert(id); c=getchar(); if(c!='\n') break; }
词汇
polynomial 多项式 | |||
---|---|---|---|