Bootstrap

Acwing基础算法模板


第一章 基础算法

AcWing基础算法

代码模板要理解背过
课下把思想搞懂,能默写出来
代码删掉重复写三四遍就差不多

第一节课

排序

快速排序

算法模板:

void quick_sort(int q[], int l, int r) {
   
	if (l >= r) {
   
		return;
	}
	int i = l - 1, j = r + 1, x = q[(l + r) / 2];
	while (i < j) {
   
		do {
   
			i++;
		} while (q[i] < x);
		do {
   
			j--;
		} while (q[j] > x);
		if (i < j) {
   
			//TODO
			swap(q[i], q[j]);     // swap()函数
		}
		quick_sort(q, l, j); // 为什么选择j ?
		quick_sort(q, j + 1, r);
	}


}
//交换两个数
if(i<j){
   
	//TODO
	int t=q[i];
	q[i]=q[j];
	q[j]=t;
}

例题: 785. 快速排序

题解:

#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n;
int q[N];
void quick_sort(int q[], int l, int r) {
   
	if (l >= r) {
   
		return;
	}
	int i = l - 1, j = r + 1, x = q[(l + r) / 2];
	while (i < j) {
   
		do {
   
			i++;
		} while (q[i] < x);
		do {
   
			j--;
		} while (q[j] > x);
		if (i < j) {
   
			//TODO
			swap(q[i], q[j]);
		}
		quick_sort(q, l, j);
		quick_sort(q, j + 1, r);
	}

}
int main() {
   
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
   
		//TODO
		scanf("%d", &q[i]);
	}
	quick_sort(q, 0, n - 1);
	for (int i = 0; i < n; i++) {
   
		//TODO
		printf("%d ", q[i]);
	}
	return 0;
}

归并排序

中间划分,合并,扫尾,还原
算法模板:

void merge_sort(int q[], int l, int r) {
   
	if (l >=  r) {
   
		return;
	}
	int mid = l + r >> 1;  // 分界点
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	int k = 0, i = l, j = mid + 1;// i是左半边区间的左边界,j是右半边区间的右边界。
	while (i <= mid && j <= r) {
     // 合二为一
		if (q[i] <= q[j]) {
   
			tmp[k++] = q[i++];
		} else {
   
			tmp[k++] = q[j++];
		}
	}
	// 扫尾
	while (i <= mid) {
   
		tmp[k++] = q[i++];
	}
	while (j <= r) {
   
		tmp[k++] = q[j++];
	}
	// tmp[]数组元素复制存储到原数组q[],还原
	for(i=l,j=0;i<=r;i++,j++){
   
		q[i]=tmp[j];
	}
	
}

快速排序是稳定的
归并排序是不稳定的
若想要快排稳定,只要让快排数组中每个数都不同,设置一个双元组,把下标也放进去,形成pair()

例题:787. 归并排序
在这里插入图片描述
题解:

#include<iostream>
using namespace std;
const int N = 100010;
int n;
int q[N], tmp[N];
void merge_sort(int q[], int l, int r) {
   
	if (l >=  r) {
   
		return;
	}
	int mid = l + r >> 1;  // 分界点
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r) {
     // 合二为一
		if (q[i] <= q[j]) {
   
			tmp[k++] = q[i++];
		} else {
   
			tmp[k++] = q[j++];
		}
	}
	// 扫尾
	while (i <= mid) {
   
		tmp[k++] = q[i++];
	}
	while (j <= r) {
   
		tmp[k++] = q[j++];
	}
	// tmp[]数组元素复制存储到原数组q[]
	for (i = l, j = 0; i <= r; i++, j++) {
   
		q[i] = tmp[j];
	}

}

int main() {
   
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
   
		//TODO
		scanf("%d", &q[i]);
	}
	merge_sort(q, 0, n - 1);
	for (int i = 0; i < n; i++) {
   
		//TODO
		printf("%d ", q[i]);
	}
	return 0;
}

二分

整数二分

会有很多边界问题
有单调性的题目一定可以二分
算法模板:

bool check(int x) {
    // 检查x是否满足某种性质
	
;