PAT知识点汇总
C++相关
64位的编译器下各数据长度
数据类型 | 占用字长 |
---|---|
char | 1个字节 |
char*(即指针变量): | 8个字节 |
short int : | 2个字节 |
int | 4个字节 |
unsigned int : | 4个字节 |
float | 4个字节 |
double | 8个字节 |
long | 8个字节 |
long long | 8个字节 |
unsigned long | 8个字节 |
关于%符号应用场合
%只能用于整形数取余
关于取整
ceil向上取整,floor向下取整
代码相关
库文件调用
cmath
要声明using namespace std;
内容:https://blog.csdn.net/fengbingchun/article/details/78171987
用scanf读入一个字符
如果用scanf读入一个字符之前用了scanf会使得该字符读入’\n’换行符,所以在使用scanf之后要读入一个字符要用getchar(){在cstdio库文件中}来读取换行符,并且你scanf“”里是怎么样的%c读到就是什么
例子:
此时%c%c连在一起字符scanf连读字符变量b是‘ ’
二把%c%c分开时
b读到就是J,所以读字符时要注意格式
字符数组相互赋值
字符数组相互赋值使用strcpy(),该函数为cstring 库文件下。
关于数组赋初值
如果是初始化,只要定义第一个元素为0,后面就全为0了,如
int a[SIZE] = {0};
如果这里改成
int a[SIZE]={1}只有第一个元素为1其他都为零。
算法相关
关于数据处理
在数据进行加减时一定要考虑数据会不会溢出
例如PATB1011 A+B 和 C (15 分)
该题考虑到了两个int类型的变量取最大值相加,取最小值相加的情况会溢出情况,详情
https://pintia.cn/problemsets/994805260223102976/problems/994805312417021952
关于时间复杂度
本题直接构建是距离的数组,然后根据题目要求的站点的位置直接两头查找的算法可以但是时间复杂度太高会出现超时(PAT时间时间100ms),所以应该避免查询次数随着要求的数据上升的求解方法,而是用空间换时间。
原版代码
#include<cstdio>
int a[100010] = { 0 };
int distance[10010] = { 0 };
int main()
{
int i = 0,n,m,c,b,distance1=0,distance2=0,k,sum=0;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d", a + i);
sum += a[i];
}
scanf("%d", &m);
k = m;
while (m--)
{
scanf("%d%d", &c, &b);
if (c <= b)
{
for (i = c - 1; i < b-1; i++)
{
distance1 += a[i];
}
distance2 = sum - distance1;
if (distance1 >= distance2)
{
distance[m] = distance2;
}
else
{
distance[m] = distance1;
}
}
else
{
for (i = b - 1; i < c- 1; i++)
{
distance1 += a[i];
}
distance2 = sum - distance1;
if (distance1 >= distance2)
{
distance[m] = distance2;
}
else
{
distance[m] = distance1;
}
}
distance1 = 0;
distance2 = 0;
}
for (i = k - 1; i >= 0; i--)
{
printf("%d\n", distance[i]);
}
return 0;
}
结果
AC代码
#include<cstdio>
int a[100010] = { 0 };
int distance[10010] = { 0 };
int main()
{
int i = 0, n, m, c, b, distance1 = 0, distance2 = 0, k, sum = 0, temp;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
scanf("%d", &temp);
sum += temp;
a[i] = sum;
}
scanf("%d", &m);
k = m;
while (m--)
{
scanf("%d%d", &c, &b);
if (c <= b)
{
distance1 = a[b - 1] - a[c - 1];
distance2 = sum - distance1;
if (distance1 >= distance2)
{
distance[m] = distance2;
}
else
{
distance[m] = distance1;
}
}
else
{
distance1 = a[c - 1] - a[b - 1];
distance2 = sum - distance1;
if (distance1 >= distance2)
{
distance[m] = distance2;
}
else
{
distance[m] = distance1;
}
}
distance1 = 0;
distance2 = 0;
}
for (i = k - 1; i >= 0; i--)
{
printf("%d\n", distance[i]);
}
return 0;
}
关于数据相加问题
要注意溢出问题
其次要注意将条件更苛刻的判断写在前面
实例:PAT1065
AC代码“
#include<cstdio>
int main()
{
long long a,b,c,r;
int flag=0,n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%lld%lld%lld", &a, &b, &c);
r=a+b;
if(a>0&&b>0&&r<0)
{
flag = 1;
}else if(a<0&&b<0&&r>=0)
{
flag =0;
}else if (r> c)
{
flag = 1;
}
else {
flag =0;
}
if (flag == 1)
{
printf("Case #%d: true\n", i + 1);
}
else {
printf("Case #%d: false\n", i + 1);
}
}
return 0;
}
这里如果先判断r十分大于c的话,就会得到错误的结构,比如r上溢为负值,r<c这显然不和题意
关于树的建立
在建树的过程中递归边界为preL>preR,等于取不了,原因在于又可能出现只有结点的区间,极叶子结点
例题PAT1138
#include<cstdio>
struct node {
int data;
node* lchild=NULL;
node* rchild=NULL;
};
const int maxv = 50100;
int pre[maxv], in[maxv], post[maxv],cnt=0;
node* creat(int preL, int preR, int inL, int inR)
{
if (preL > preR)
{
return NULL;
}
node* root = new node;
root->data = pre[preL];
int k;
for (int i = inL; i <=inR;i++)
{
if (in[i] == pre[preL])
{
k = i;
break;
}
}
int leftnumb = k - inL;
root->lchild = creat(preL + 1, preL + leftnumb, inL, k - 1);
root->rchild = creat(preL + leftnumb + 1, preR, k + 1, inR);
return root;
}
void postorder(node* root)
{
if (root == NULL)
{
return;
}
postorder(root->lchild);
postorder(root->rchild);
post[cnt++] = root->data;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", pre + i);
}
for (int i = 0; i < n; i++)
{
scanf("%d", in + i);
}
node* root = new node;
root = creat(0, n-1, 0, n-1);
postorder(root);
printf("%d", post[0]);
return 0;
}