PAT知识点汇总

C++相关

64位的编译器下各数据长度

数据类型占用字长
char1个字节
char*(即指针变量):8个字节
short int :2个字节
int4个字节
unsigned int :4个字节
float4个字节
double8个字节
long8个字节
long long8个字节
unsigned long8个字节

关于%符号应用场合

%只能用于整形数取余

关于取整

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值