基础算法
-
快排:
- 确定分界点
- 调整区间(重点)
- 递归处理左右两段
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int q[N];
void quick_sort(int q[],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);
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 0; i < n; i ++) scanf("%d",&q[i]);
quick_sort(q,0,n-1);
for(int i = 0; i < n; i ++) printf("%d ",q[i]);
return 0;
}
- 归并排序:
- 确定分界点
- 递归排序左右两边
- 合二为一
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int q[N],temp[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]) temp[k++] = q[i++];
else temp[k++] = q[j++];
}
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];
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 0; i < n; i ++ ) scanf("%d",&q[i]);
merge_sort(q,0,n-1);
for(int i = 0; i < n; i ++ ) printf("%d ",q[i]);
return 0;
}
-
整数二分:
-
只需要注意如果是l = mid 那么 mid = l + r + 1 >> 1;
如果是r = mid 那么mid = l + r >> 1;
-
剩余的就是对check的书写
-
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
int main()
{
int n,q;
cin >> n >> q;
for(int i = 0; i < n; i ++ ) scanf("%d",&a[i]);
while(q -- )
{
int x;
cin >> x;
int l = 0, r = n - 1;
while(l < r)
{
int mid = l + r >> 1;
if(a[mid] >= x) r = mid;
else l = mid + 1;
}
if(a[l] != x) cout << "-1 -1" << endl;
else
{
cout << l << ' ';
l = 0, r = n - 1;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(a[mid] <= x) l = mid;
else r = mid - 1;
}
cout << l << endl;
}
}
return 0;
}
- 高精度加法:
#include<bits/stdc++.h>
using namespace std;
vector<int> add(vector<int>&A , vector<int>&B)
{
vector<int> C;
int t = 0;
for(int i = 0; i < A.size() || i < B.size(); i ++ )
{
if(i < A.size()) t += A[i];
if(i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if(t) C.push_back(1);
return C;
}
int main()
{
string a,b;
cin >> a >> b;
vector<int> A,B;
for(int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
for(int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
auto C = add(A,B);
for(int i = C.size() - 1; i >= 0; i -- ) printf("%d",C[i]);
return 0;
}
- 高精度减法:
#include<bits/stdc++.h>
using namespace std;
bool cmp(vector<int> &A, vector<int> &B)
{
if(A.size() != B.size()) return A.size() > B.size();
for(int i = A.size() - 1; i >= 0; i -- ){
if(A[i] != B[i])
return A[i] > B[i];
}
return true;
}
vector<int> sub(vector<int> &A, vector<int> &B)
{
vector<int> C;
for(int i = 0, t = 0; i < A.size(); i ++ )
{
t = A[i] - t;
if(i < B.size()) t -= B[i];
C.push_back((t + 10 ) % 10);
if(t >= 0) t = 0;
else t = 1;
}
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a,b;
cin >> a >> b;
vector<int> A,B;
for(int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
for(int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
if(cmp(A,B))
{
vector<int> C = sub(A,B);
for(int i = C.size() - 1; i >= 0; i -- ) printf("%d",C[i]);
}
else{
vector<int> C = sub(B,A);
printf("-");
for(int i = C.size() - 1; i >= 0; i -- ) printf("%d",C[i]);
}
return 0;
}
- 高精度乘法:
- 代码与加法的相似,可以结合起来记忆
#include<bits/stdc++.h>
using namespace std;
vector<int> mul(vector<int> &A,int b)
{
vector<int> C;
int t = 0;
for(int i = 0; i < A.size() | t; i ++ )
{
if(i < A.size()) t += A[i] * b;
C.push_back(t % 10);
t /= 10;
}
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> A;
for(int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
vector<int> C = mul(A,b);
for(int i = C.size() - 1; i >= 0; i -- ) printf("%d",C[i]);
return 0;
}
- 高精度除法:
- 它跟乘法的区别在于,它是从高位开始算,而乘法加法减法都是从低位开始算起的
#include<bits/stdc++.h>
using namespace std;
vector<int> div(vector<int> &A, int b, int &r)
{
vector<int> C;
for(int i = A.size() - 1; i >= 0; i -- )
{
r = r * 10 + A[i];
C.push_back(r / b);
r %= b;
}
reverse(C.begin(), C.end());
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string a;
int b, r = 0;
cin >> a >> b;
vector<int> A;
for(int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
vector<int> C = div(A, b, r);
for(int i = C.size() - 1; i >= 0; i -- ) printf("%d",C[i]);
cout << endl << r << endl;
return 0;
}
-
前缀和(子矩阵求和,一维同理)
-
一维:
- 求前缀和公式:s[i] = s[i - 1] + a[i];
- 求[l,r]区间的和公式,等于s[r] - s[l - 1];
-
二维的:
- 求前缀和公式:s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
- 求子矩阵的和公式:s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];
-
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int m,n,q;
int s[N][N],a[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]);
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[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]);
}
return 0;
}
所有例题和代码思路均来自AcWing!!!