文章目录
快速排序模版
//快速排序
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