一、基础算法
1.快速排序
void quick_sort(int q[N], int l, int r) {
if (l > r) return;//判断边界
int x = q[l], i = l - 1, j = r + 1;//边界点 双指针
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j)swap(q[i], q[j]);
}
quick_sort(q, l, j),quick_sort(q,j + 1, r);
}
2.归并排序–分治
int tmp[];//存放排序好的最终序列
void merge_sort(int q[], int l, int r) {//q[]代排序数组,l左边界 右边界(闭区间)
if (l > r) return;
int mid = l + r >> 1;//取中间点
merge_sort(q, l, mid), merge_sort(q, mid + 1, r);//递归排序left、right部分
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数组
for (i = l, j = 0; j <= r; i++, j++) q[i] = tmp[j];
//将排序好序列复制到原数组q
}
3.整数二分
bool check(int x){/* */}//检查x是否满足某种性质
//区间[l,r]被划分成[l,mid]和[mid+1,r]同时使用
int bserach_1(int q[], int l, int r,int x)
{
while (l < r)
{
int mid = (l + r + 1) >> 1;
if (check(mid)) l = mid;//check(mid)判断mid是否满足某种性质
else r = mid - 1;
}
return 1;
}
//区间[l,r]被划分成[l,mid-1]和[mid,r]同时使用
int bserach_2(int q[], int l, int r, int x)
{
while(l < r)
{
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
return 1;
}
4.浮点数二分
一般用来求解开方后的结果
//bool check(double x) {/* ... */} // 检查x是否满足某种性质
double bsearch_3(double l, double r)
{
const double eps = 1e-6; // eps 表示精度,取决于题目对精度的要求
while (r - l > eps)
{
double mid = (l + r) / 2;
if (mid*mid>=x) r = mid;
else l = mid;
}
return l;
}
前缀和
求某一段区间内所有数的和
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m;
int s[N],a[N];
int main()
{
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; i ++ )
{
scanf("%d",&a[i]);
s[i] = s[i-1] + a[i];
}
while( m -- )
{
int l, r;
scanf("%d %d",&l,&r);
printf("%d\n",s[r] - s[l - 1]);
}
}
差分
差分可看作前缀和的逆运算
未看:二维差分 797.差分矩阵 基础算法二
#include <iostream>
using namespace std;
const int N = 100010;
int n, m;
int a[N], b[N];
void insert(int l, int r, int c)
{
b[l] += c;
b[r + 1] -= c;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++ ) scanf("%d",&a[i]);
for(int i = 1; i <= n; i ++ ) insert(i, i, a[i]);
while(m -- )
{
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
insert(l, r, c);
}
for(int i = 1; i <= n; i ++ )
{
b[i] += b[i - 1];
printf("%d ",b[i]);
}
return 0 ;
}
双指针
799.最长不重复连续子序列
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
int a[N], cnt[N]; // cnt[] 记录 a[] 每个数重复出现的次数
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
int res = 0; // 记录最长不重复子序列的长度
for(int i = 0, j = 0; j < n; j ++ )
{
cnt[a[j]] ++; // 记录 a[i] 数字出现次数
while(cnt[a[j]] > 1)
{
cnt[a[i]] --;
i ++;
}
res = max(res, j - i + 1);
}
cout << res << endl;
return 0;
}
位运算
#include <iostream>
using namespace std;
int lowbit(int x) // 返回x二进制表示中的最后一位1
{
return x & -x;
}
int main()
{
int n;
cin >> n;
while(n -- )
{
int x;
cin >> x;
int res = 0; // 只能在while外部定义--每次输出一个数中1的个数后置0
while(x)
{
x -= lowbit(x); // 每一次减去二进制中的最后一位1,x为0统计完所有1的个数退出while
res ++;
}
cout << res << " ";
}
return 0;
}
基础算法3 01:12:31 离散化往后内容未看