基础算法-模板习题一


快速排序模版

//快速排序
void quick_sort(int q[], int l, int r) {
	if (l >= r) return;

	int x = q[l];//随机确定一个分界点
	int i = l - 1;//初始化位置
	int j = r + 1;//初始化位置

	while (i < j) {
		while (q[++i] < x);//i指向的元素小于x,则右移,一直移动到指向的元素大于等于x
		while (q[--j] > x);//j指向的元素大于x,则左移,一直移动到指向的元素小于等于x
		if (i < j) swap(q[i], q[j]);//在满足以上情况时,交换元素值
	}//结束循环的条件时i=j,相遇位置

	quick_sort(q, l, j);//递归处理左段
	quick_sort(q, j + 1, r);//递归处理右段
}

快速排序习题——求数组中第 k 小 的数

在这里插入图片描述
解题思路:
在这里插入图片描述

#include<iostream>
using namespace std;

const int N = 100010;

int n, k;
int q[N];

//求第k个数
int quick_sort(int l, int r, int k) {
	if (l == r) return q[l];

	int x = q[l], i = l - 1, j = r + 1;

	while (i < j) {
		while (q[++i] < x);
		while (q[--j] > x);

		if (i < j) swap(q[i], q[j]);
	}
	int sl = j - l + 1;
	if (k <= sl) return quick_sort(l, j, k);

	return quick_sort(j + 1, r, k - sl);

}

int main() {
	cin >> n >> k;

	for (int i = 0; i < n; i++) cin >> q[i];

	cout << quick_sort(0, n - 1, k) << endl;

	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;
	int i = l;
	int j = mid + 1;
	while (i <= mid && j <= r) {
		if (q[i] <= q[j]) temp[k++] = q[i++];
		else {
			temp[k++] = q[j++];
		}
	}
	//结束while循环的状态是两个序列有一个已经空了
	while (i <= mid)  temp[k++] = q[i++] ;
	while (j <= r) temp[k++] = q[j++];

	//将temp数组中存的结果重新还给q数组
	for (int i = l, j = 0; i <= r; i++, j++) q[i] = temp[j];
}

归并排序习题——求逆序对的个数问题

在这里插入图片描述
在这里插入图片描述

#include<iostream>
using namespace std;

typedef long long LL;
const int N = 100010;

int n;
int q[N], temp[N];

LL merge_sort(int l, int r) {
	if (l >= r) return 0;

	int mid = l + r >> 1;
	LL res = merge_sort(l,mid) + merge_sort(mid + 1, r);

	//归并的过程
	int k = 0;
	int i = l;
	int j = mid + 1;
	while (i <= mid && j <= r) {
		if (q[i] <= q[j]) temp[k++] = q[i++];
		else
		{
			temp[k++] = q[j++];
			res += mid - i + 1;
		}
	}
		//扫尾
		while (i <= mid)temp[k++] = q[i++];
		while (j <= r)temp[k++] = q[j++];

		//物归原主
		for (int i = l, j = 0; i <= r; i++, j++)q[i] = temp[j];
		return res;
}

int main() {
	cin >> n;
	for (int i = 0; i < n; i++) cin >> q[i];

	cout<< merge_sort( 0, n - 1)<<endl;
	return 0;
}

二分习题——求数的三次方根

在这里插入图片描述
在这里插入图片描述

#include<iostream>
using namespace std;

int main() {
	double x;
	cin >> x;

	double l = -10000;
	double r = 10000;

	while (r - l > 1e-8) {
		double mid = (l + r) / 2;
		if (mid * mid * mid >= x) r = mid;
		else l = mid;
	}

	printf("%lf\n", l);
	return 0;
}

一维前缀和习题——求前缀和

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

#include<iostream>
using namespace std;

const int N = 100010;

int n,m;
int a[N], s[N];

int main() {
	cin >> n >> m;

	for (int i = 1; i <= n; i++) cin >> a[i];

	//求前缀和数组
	for (int i = 1; i <= n; i++)	s[i] = s[i - 1] + a[i];
	while (m--) {
		int l, r;
		cin >> l >> r;
		cout << s[r] - s[l - 1] << endl;
	}
	return 0;
}

二维前缀和习题——求子矩阵的和

在这里插入图片描述

在这里插入图片描述
前缀和:两个核心操作
在这里插入图片描述

#include<iostream>

const int N = 1010;

int m, n, q;
int a[N][N], s[N][N];

int main() {
	scanf("%d%d%d", &n, &m, &q);

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			scanf("%d", &a[i][j]);
		}
	}
	//初始化前缀和数组
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];//求前缀和

	//询问
	while (q--) {
		int x1, y1, x2, y2;
		scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
		printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);//算子矩阵的和
	}
	return 0;
}
//输入
//3 4 3
//1 7 2 4
//3 6 2 8
//2 1 2 3
// 输出
//1 1 2 2
//17
//2 1 3 4
//27
//1 3 3 4
//21

一维差分习题——求差分

在这里插入图片描述

在这里插入图片描述
1、a[1~L-1] 无影响
2、a[L~R] 加上了C
3、a[R+1~N] 无影响

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>

using namespace std;

const int N = 100010;

int m, n;
int a[N], b[N];


void insert(int l, int r, int c) {
	b[l] += c;
	b[r + 1] -= c;
}
int main() {
	cin>>n>>m;
	for (int i = 1; i <= n; i++) cin >> a[i];

	//从前往后,插入构造
	for (int i = 1; i <= n; i++) insert(i, i, a[i]);

	while (m--)
	{
		int l, r, c;
		cin >> l >> r >> c;
		insert(l, r, c);

	}
	for (int i = 1; i <= n; i++) b[i] += b[i - 1];

	for (int i = 1; i <= n; i++) printf("%d ", b[i]);

	return 0;
}

//输入
//6 3
//1 2 2 1 2 1
//1 3 1
//3 5 1
//1 6 1
//输出
//3 4 5 3 4 2

二维差分习题——求差分矩阵

在这里插入图片描述

以下图中,S代表差分数组B
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>
using namespace std;

const int N = 1010;
int n2, m2, q1;
int a[N][N];//原矩阵
int b[N][N];//差分矩阵

void insert(int x1, int y1, int x2, int y2, int c) {
	b[x1][y1] += c;
	b[x2 + 1][y1] -= c;
	b[x1][y2 + 1] -= c;
	b[x2 + 1][y2 + 1] += c;
}
int main() {

	scanf("%d%d%d", &n2, &m2, &q1);

	for (int i = 1; i <= n2; i++)
		for (int j = 1; j <= m2; j++)
			scanf("%d", &a[i][j]);

	for (int i = 1; i <= n2; i++)
		for (int j = 1; j <= m2; j++)
			insert(i, j, i, j, a[i][j]);

	while (q1--)
	{
		int x1, x2, y1, y2, c;
		cin >> x1 >> y1 >> x2 >> y2 >> c;
		insert(x1, y1, x2, y2, c);

	}

	for (int i = 1; i <= n2; i++)
		for (int j = 1; j <= m2; j++)
			b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];

	for (int i = 1; i <= n2; i++) {
		for (int j = 1; j <= m2; j++) printf("%d ", b[i][j]);
		puts("");
	}

	return 0;
}
//输入
//3 4 3
//1 2 2 1
//3 2 2 1
//1 1 1 1
//1 1 2 2 1
//1 3 2 3 2
//3 1 3 4 1
//
//输出
//2 3 4 1
//4 3 4 1
//2 2 2 2 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gloomy_coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值