基础算法模板汇总(大全)
一、排序
sort排序
sort(a, a + n, cmp);
cmp函数(可不加,默认排序为从小到大)为判断大小的函数
//从大到小
bool cmp(int a, int b)
{
return a > b;
}
//从小到大
bool cmp(int a, int b)
{
return a < b;
}
sort排序(结构体)
struct node
{
int b;
int p;
int v;
}a[100];
sort(a, a + n, cmp);
bool cmp(node x, node y)
{
return x.b > y.b
}
冒泡排序
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n - i - 1; j++)
{
if(a[j + 1] < a[j]) swap(a[j + 1], a[j]);
}
}
快速排序
void quick_sort(int a[], int l, int r)
{
if(l >= r) return;
int i = l - 1, j = r + 1, x = l + r >> 1 ;//'+'的优先级高于'>>'移位运算符
while(i < j)
{
do i++;while(a[i] < x);
do j--;while(a[j] > x);
if(i < j) swap(a[i], a[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
归并排序
void merge_sort(int a[], int l, int r)
{
if(l >= r) return;
int mid = l + r >> 1;
merge_sort(a, l, mid);
merge_sort(a, mid + 1, r);
int k = 0, i = l, j = mid + 1;
whlie(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--];
for(int i = l, k = 0; i <= r; i++)
q[k++] = tmp[i++];
}
二、高精度算法
高精度乘法
#include<bits/stdc++.h>
using namespace std;
char a1[101], b1[101];
int a[101], b[101], c[10001], lena, lenb, lenc, i, j, x;
int main()
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
scanf("%s", a1);
scanf("%s", b1);
lena = strlen(a1);
lenb = strlen(b1);
for(i = 0; i <= lena - 1; i++) a[lena - i] = a1[i] - 48;
for(i = 0; i <= lenb - 1; i++) b[lenb - i] = b1[i] - 48;
for(i = 1; i <= lena; i++)
{
x = 0;
for(j = 1; j <= lenb; j++)
{
c[i + j - 1] = a[i] * b[j] + x + c[i + j - 1];
x = c[i + j - 1] / 10;
c[i + j - 1] %= 10;
}
c[i + lenb] = x;
}
lenc = lena + lenb;
while(c[lenc] == 0 && lenc > 1)
lenc--;
for(i = lenc; i >= 1; i--)
cout << c[i];
cout << endl;
return 0;
}
高精度除法
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
string a1;
int b, yu;
int a[N], result[N];
int main()
{
cin >> a1 >> b;
int lena = a1.size();
for(int i = 0; i < lena; i++)
{
a[i] = a1[lena - i - 1] - '0';
}
for(int i = lena - 1; i >= 0; i--)
{
yu = yu * 10 + a[i];
result[i] = yu / b;
yu %= b;
}
int tmp = lena;
while(result[tmp] == 0 && tmp > 0) tmp--;
for(int i = tmp; i >= 0; i--) cout << result[i];
cout << endl;
cout << yu << endl;
return 0;
}
高精度加法(我的博客)
#include <bits/stdc++.h>
using namespace std;
char a1[2000], b1[2000];
int a[2000], b[2000], c[2000];
int main()
{
cin >> a1 >> b1;
for(int i = 0; i < strlen(a1); i++)
{
a[strlen(a1) - 1 - i] = a1[i] - '0';
}
for(int i = 0; i < strlen(b1); i++)
{
b[strlen(b1) - 1 - i] = b1[i] - '0';
}
for(int i=0;i<max(strlen(a1),strlen(b1));i++)
{
c[i] += (a[i] + b[i]);
c[i + 1] = c[i] / 10;
c[i] %= 10;
}
int add = 0;
if(c[max(strlen(a1), strlen(b1))] != 0)
{
add = 1;
}
for(int i = max(strlen(a1), strlen(b1)) + add - 1; i >= 0; i--)
{
cout << c[i];
}
return 0;
}
高精度减法(我的博客)
#include <bits/stdc++.h>
using namespace std;
int a[210], b[210], c[210];
char s[210];
void sub()
{
int i;
c[0] = a[0];
for(i = 1; i <= a[0]; i++) c[i] = a[i] - b[i];
for(i = 1; i <= c[0]; i++)
if(c[i] < 0)
{
c[i] += 10;
c[i + 1] -= 1;
}
i = c[0];
while(c[i] == 0) i--;
c[0] = i;
}
int main()
{
int i, len, k;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
scanf("%s", s);
len = strlen(s);
k = 0;
for(i = len - 1; i >= 0; i--) a[++k] = s[i]-'0';
a[0] = len;
scanf("%s", s);
len = strlen(s);
k = 0;
for(i = len - 1; i >= 0; i--) b[++k] = s[i] - '0';
b[0] = len;
sub();
for(i = c[0]; i >= 1; i--) printf("%d", c[i]);
return 0;
}
三、二分
整数二分
//区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用
int erfen1(int l, int r)
{
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
return 1;
}
//区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用
int erfen2(int l, int r)
{
while(l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
r = mid - 1;
}
return 1;
}
浮点数二分
double erfen(double l, double r)
{
const double e = 1e-6;
while(l < r)
{
double mid = (l + r) / 2;
if(check(mid)) r = mid;
else l = mid;
}
return 1;
}
四、前缀和
一维前缀和
for(int i = 1; i <= n; i++)
{
s[i] = s[i - 1] + s[i];
}
cout << s[r] - s[l - 1] << endl;
二维前缀和
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + map[i][j];
for(int i = 1; i <= k; i++)
{
int x1, x2, y1, y2;
cin >> x1 >> y1 >> x2 >> y2;
cout <<(dp[x2][y2] + dp[x1 - 1][y1 - 1] - dp[x1 - 1][y2] - dp[x2][y1 - 1]) << endl;
}
五、差分
一维差分
for(int i = 1;i <= n; i++)
{
b[i] = a[i] - a[i - 1]; //构建差分数组
}
int l, r, c;
while(m--)
{
scanf("%d%d%d", &l, &r, &c);
b[l] += c; //表示将序列中[l, r]之间的每个数加上c
b[r + 1] -= c;
}
for(int i = 1;i <= n; i++)
{
b[i] += b[i - 1]
printf("%d ",b[i]);
}
二维差分
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c; //构建差分数组
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1]; //二维前缀和
}
}
六、离散化
vector<int> alls;
sort(alls.begin(), alls.end());
alls.erase(unique(alls.begin(), alls.end()));
int find(int x)
{
int l = 0, r = alls.size() - 1;
while(l < r)
{
int mid = l + r >> 1;
if(alls[mid] >= x) r = mid;
else l = mid + 1;
}
return r + 1;
}
七、搜索与回溯
int search(int t)
{
if(满足输出条件)
{
输出解;
}
else
{
for(int i=1;i<=尝试方法数;i++)
if(满足进一步搜索条件)
{
为进一步搜索所需要的状态打上标记;
search(t + 1);
恢复到打标记前的状态;//也就是说的{回溯一步}
}
}
}
八、广度优先搜索(我的博客)
head = 0, tail = 1;
num++;
bz[a][b] = 0;
h[1][1] = a;
h[1][2] = b;
do
{
head++;
for(i = 0; i <= 3; i++)
{
x = h[head][1] + dx[i];
y = h[head][2] + dy[i];
if((x >= 0) && (x < m) && (y >= 0) && (y < n) && (bz[x][y]))
{
tail++;
bz[x][y] = 0;
h[tail][1] = x;
h[tail][2] = y;
}
}
}while(head < tail);
}