PAT class a summary

Posted by sissy on Sat, 25 Dec 2021 14:42:15 +0100

PAT class a summary - Beginner Level

1, Mathematics

It is often used as a basic 20 point sub topic in PAT. The change of the topic is relatively novel, but the basic idea remains the same.

1.1 prime

Egyptian screening method: to obtain all primes within natural number n, the multiples of all primes not greater than root n must be eliminated, and the rest is prime.

int flag[maxn] = {false};
int prime[maxn], pNum = 0;

void findprime(int n)
{
	flag[0] = flag[1] = true;
	for (int i = 2; i <= n; i++)
	{
		if (!flag[i])
		{
			prime[pNum++] = i;
			for (int j = i*i; j <= n; j+=i)
			{
				flag[j] = true;
			}
		}
	}
}

Euler sieve method: on the basis of Ehrlich sieve method, each composite number is screened only once by its minimum quality factor, so as to achieve the purpose of non repetition.

int flag[maxn] = {false};
int prime[maxn];
void eulerSieve(int n)
{
	fill(flag, flag + maxn, 0);
	flag[0] = flag[1] = true;
	fill(prime, prime + maxn, 0);
	for (int i = 2; i <= maxn; i++) {
		if (!flag[i]) {
			prime[++prime[0]] = i;
		}

		for (int j = 1; j <= prime[0] && i * prime[j] <= maxn; j++) {
			flag[i * prime[j]] = true;
			if (i % prime[j] == 0) {
				break;
			}
		}
	}
}

[note]:

1. Instead of using the multiple of i to eliminate the composite number, we use the prime number recorded in prime in ascending order as the smallest prime factor to eliminate the composite number

2. Explanation of i%prime[j] == 0 break:

When i is a multiple of prime[j], i = k*prime[j]. If you continue to operate j+1, i * prime[j+1] = prime[j] * k * prime[j+1],

Here, prime[j] is the smallest prime factor. It will repeat when i = k * prime[j+1], so it jumps out of the loop.

1.2 maximum common divisor

int gcd(int a, int b)
{
	return b == 0 ? a : gcd(b, a%b);
}

[note]: a > 0, b > 0

1.3 fast power

long long ksm(long long a, int b)
{
	long long base = a, ans = 1;
	while (b != 0) {
		if (b & 1 != 0)
		{
			ans *= base;
		}
		base *= base;
		b >> 1;
	}
	return ans;
}

**[note]: * * in number theory, it is also called the repeated square method. It should be noted here that when the power is an odd number, it needs to multiply the base once more (because dividing the odd number by 2 will throw away a base factor).

1.4 binary conversion

Use strings to represent numbers and az to represent 1035

long long convert(string n, long long radix)
{
	long long base = 1;
	long long num = 0;
	for (auto lt = n.rbegin(); lt != n.rend();lt++) {
		int tmp = isdigit(*lt) ? *lt - '0' : *lt - 'a' + 10;
		num += tmp*base;
		base *= radix;
	}

	return num;

}

1.5 string addition

//strlen(s1)>strlen(s2)
string addstring(string s1, string s2)
{
	int carry = 0;
	for (int i = (int)s1.size() - 1, t; i >= 0; i--) {
		t = (s1[i] - '0') + (s2[i] - '0') + carry;
		s1[i] = t % 10 + '0';
		carry = t / 10;
	}
	if (carry > 0) s1.insert(s1.begin(), carry + '0');

	return s1;

}

1.6 large number operation

struct  bign
{
	int len;
	int d[110];
	bign() {
		len = 0;
		memset(d, 0, sizeof(d));
	}

};

bign convert(char s[])
{
	bign a;
	a.len = strlen(s);
	for (int i = a.len - 1; i >= 0; --i)
	{
		a.d[a.len - 1 - i] = s[i] - '0';
	}
	return a;
}

bign add(bign a) {
	bign c;
	int carry = 0;
	c.len = 0;
	for (int i = 0; i < a.len; i++)
	{
		int temp = a.d[i] + a.d[a.len - 1 - i] + carry;
		c.d[c.len++] = temp % 10;
		carry = temp / 10;
	}

	if (carry != 0) {
		c.d[c.len++] = carry;
	}
	
	return c;

}

2, Binary tree

It often appears as a 25 point question in PAT and occasionally in the form of 30 points (Autumn on September 11, 2021). Its basic theory is not difficult, but in the following cases:

1. Middle order pre order tree 2, middle order post order tree 3, hierarchical middle order tree 4, binary search tree 5, AVL tree 6, heap 7, complete binary tree

According to the trend of test questions over the years, the main test point gradually changes from tree to heap, that is, heap is presented in the form of complete binary tree

The test questions of binary tree can not build a tree without building a tree, and it is relatively simple to use static to build a tree

2.1 sequence conversion

As the core of the core test site tree, you need to be very skilled in understanding and mastering the transformation of tree sequence (no tree). When doing questions, there is an idea that with two sequences including middle sequence, there will be a tree, and other problems can be carried out on the sequence.

**[note]: * * understanding is the key. Don't memorize by rote.

Given the middle sequence and the pre sequence, find the sequence and post sequence:

vector<int> pre, in,post, le[maxn];
//taril(0,0,n-1,0);
void taril(int root, int start, int end, int level)
{
	if (start > end)
	{
		return;
	}
	int idx = pre[root];
	int pos = start;
	while (in[pos] != idx) pos++;
	le[level].push_back(in[pos]);		//Record level
	taril(root + 1, start, pos - 1, level + 1);
	taril(root + 1, pos + 1, end, level + 1);
	post.push_back(idx);	//Post record sequence
	return;
}

After the sequence and pre sequence are known, calculate the sequence and pre sequence:

vector<int> pre, in,post, le[maxn];
//taril(n-1,0,n-1,0);
void taril(int root, int start, int end, int level) {
	if (start > end)
	{
		return;
	}

	int idx = post[root];
	int pos = start;
	while (in[pos] != idx) pos++;
	pre.push_back(in[pos]);		//Record preamble
	le[level].push_back(in[pos]);	//Record level
	
	taril(root - 1 - (end - pos), start, pos - 1, level + 1);
	taril(root - 1, pos + 1, end, level + 1);
	
	return;

}

2.2 heap complete binary tree

Use an int heap[N+1] to record (N nodes, label starts from 1)

The most important core property of a complete binary tree is to grasp that for a subscript i, its left subscript is 2 * i and its right subscript is 2 * i + 1

Take the large top pile as an example

Upward adjustment:

void update(int low, int high)
{
	int i = high, j = high >> 1;
	while (j >= low) {
		if (heap[i] > heap[j])
		{
			swap(heap[i], heap[j]);
			i = j;
			j = i >> 1;
		}
		else {
			break;
		}
	}
}

Downward adjustment:

void downAdj(int low, int high)
{
	int i = low, j = low << 1;
	while (j <= high) {
		if (j + 1 <= high&&heap[j]<heap[j + 1])
		{
			j++;

		}
		if (heap[i] < heap[j])
		{
			swap(heap[i], heap[j]);
			i = j;
			j = i << 1;
		}
		else {
			break;
		}
	}

}

Heap sort:

void heapSort(int n) {
	for (int i = n / 2; i > 0; i--) {
		downAdj(i, n);
	}

	for (int i = n; i > 1; i--) {
		swap(heap[1], heap[i]);
		downAdj(1, i - 1);
	}
}

2.3 binary search tree BST

When building a tree, the idea of inserting from the root node is adopted

1. For each node, the left side is small and the right side is large (which side is equal to the meaning of the question)

2. The middle order of BST tree is the sequence of data from small to large

2.4 AVL tree

struct node {
	int data;
	node *lchild, *rchild;
	int heigh;
};

int getHeight(node * root)
{
	if (root == NULL) {
		return 0;
	}
	return root->heigh;

}

int getBalance(node *root)
{
	return getHeight(root->lchild) - getHeight(root->rchild);
}

void updateHeight(node *&root) {
	root->heigh = max(getHeight(root->lchild), getHeight(root->rchild)) + 1;
}

void L(node * &root)
{
	node *tmp = root->rchild;
	root->rchild = tmp->lchild;
	tmp->lchild = root;
	updateHeight(root);
	updateHeight(tmp);
	root = tmp;
}

void R(node * &root)
{
	node * tmp = root->lchild;
	root->lchild = tmp->rchild;
	tmp->rchild = root;
	updateHeight(root);
	updateHeight(tmp);
	root = tmp;

}

void insert(node* &root, int data)
{
	if (root==NULL)
	{
		root = new node();
		root->heigh = 1;
		root->lchild = root->rchild = NULL;
	}
	else {
		if (data < root->data)
		{
			insert(root->lchild, data);
			if (getHeight(root) == 2) {
				if (getHeight(root->lchild) == 1)
				{
					R(root);
				}
				else if (getHeight(root->lchild) == -1) {
					L(root->lchild);
					R(root);
				}
			}

		}
		else {
			insert(root->rchild, data);
			if (getHeight(root) == -2) {
				if (getHeight(root->rchild) == -1)
				{
					L(root);
				}
				else if (getHeight(root->rchild) == 1) {
					R(root->rchild);
					L(root);
				}
			}
		}
	}

}

2.5 LCA issues

The core grasps the middle order, records the middle order position of each node, and starts from the root node (the order around the root). The first middle order position is the point between the middle order positions of the two points, which is its lowest common ancestor.

Topics: C++ Algorithm data structure