[acwing][模板]基本演算法模板
阿新 • • 發佈:2021-09-07
快排
void quick_sort(int a[], int l, int r) {
if (l >= r)return;
int p = a[l];
int i = l - 1, j = r + 1;//左右各移動一格,配合do-while
while (i < j) {
do i++; while (a[i] < p);
do j--; while (a[j] > p);
if (i < j)swap(a[i], a[j]);
}
quick_sort(a, l, j);
quick_sort(a, 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 temp[N]; int k = 0, i = l, j = mid + 1; while (i <= mid && j <= r) { if (a[i] <= a[j])temp[k++] = a[i++]; else temp[k++] = a[j++]; } while (i <= mid)temp[k++] = a[i++]; while (j <= r)temp[k++] = a[j++]; for (int t = 0; t <= r - l; t++) { a[l + t] = temp[t]; } }
高斯消元
#include<bits/stdc++.h> using namespace std; #define ep 0.00001 const int N = 100; int n; double a[N][N]; int main() { cin >> n; for (int i = 0; i < n; i++) { for (int j = 0; j <= n; j++) { cin >> a[i][j]; } } for (int j = 0; j < n; j++) { int m = j; for (int i = j; i < n; i++) { if (fabs(a[i][j]) > fabs(a[m][j])) { m = i; } } swap(a[m],a[j]); if (a[j][j]) { for (int z = n; z >= j; z--) { a[j][z] /= a[j][j]; } } for (int x = j + 1; x < n; x++) { for (int y = n; y >= j; y--) { a[x][y] -= a[x][j]*a[j][y]; } } } for (int j = n - 1; j >= 0; j--) { for (int i = j - 1; i >= 0; i--) { a[i][n] -= a[j][n] * a[i][j]; a[i][j] = 0; } } int flag = 1; for (int re = 0; re <= n - 1; re++) { if (a[n - 1][re])flag = 0; } if (flag && !a[n - 1][n]) { puts("all"); } else if (flag&&a[n - 1][n]) { puts(" no result"); } else { for (int i = 0; i < n; i++) { cout << a[i][n]; puts(""); } } }
高精度
vector<int> add(vector<int>&a, vector<int>&b) { int la = a.size(); int lb = b.size(); int t = 0; vector<int> res; for (int i = 0; i < la || i < lb; i++) { if (i < la)t += a[i]; if (i < lb)t += b[i]; res.push_back(t % 10); t /= 10; } if (t)res.push_back(t); //輸出部分 for (int i = res.size() - 1; i >= 0; i--) { cout << res[i]; } return res; } bool cmp(vector<int>&a, vector<int>&b) {// check whether a>=b if (a.size() != b.size())return a.size() > b.size();//trick for (int i = a.size(); i >= 0; i--) { if (a[i] != b[i])return a[i] > b[i]; } return true; } vector<int> subtract(vector<int>&a, vector<int>&b) {//a>b 且a,b均為正整數 vector<int> c; int t = 0; for (int i = 0; i < a.size(); i++) { t = a[i] - t; if (i < b.size())t -= b[i]; c.push_back((t + 10) % 10);//trick :if t<0 push t+10 if t>0 return t; if (t < 0)t = 1; else t = 0; } while (c.size() > 1 && !c.back())c.pop_back();//c.size()should >1 cause if ans is 0,0shoule be kept return c; } vector<int> mul(vector<int>a, int b) {//廣義進位思想 vector<int> c; int t = 0; for (int i = 0; i < a.size() || t; i++) {//trick 合在一起寫,不用單獨寫t>0 if(i<a.size())t += a[i] * b; c.push_back(t % 10); t /= 10; } return c; } vector<int> div(vector<int>a, int b,int&r) {//r是餘數 ,引用傳值 vector<int > c; r = 0; for (int i = a.size() - 1; i >= 0; i--) { r = r * 10 + a[i]; c.push_back(r / b); r = r % b; } reverse(c.begin(), c.end());//trick while (c.size() > 1 && !c.back())c.pop_back(); return c; }
字首和與差分
/*字首和與差分
二維字首和公式 :初始化: s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]
查詢 以(x1,y1 )(x2,y2)為頂點的矩形面積 =s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][x2-1]
差分 把一個數組看成另一個數組的字首和,對於[l,r]區間的每一個數都加r的操作,可以實現為差分陣列的
a[l]+=c,a[r+1]-=c
*/
void insert(int b[5][5],int x1, int x2, int y1, int y2, int c) {
b[x1][y1] += c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y1] -= c;
b[x2 + 1][y2 + 1] += c;
}
離散化
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int, int> PII;
const int N = 300010;//2m+n
vector<int> f;
int a[N],s[N];//f是離散化的對映集,a是與對映集對應的值集
int find(int x) {//找出x的離散化後的下標
int l = 0, r = f.size() - 1;
while (l < r) {
int mid = l + r >> 1;
if (f[mid] >= x)r = mid;
else l = mid + 1;
}
return l+1;
}
int main() {
int n,m;
vector<PII> add;
vector<PII > query;
cin >> n>>m;
while (n--) {
int x, c;
cin >> x >> c;
add.push_back(make_pair(x,c));
f.push_back(x);
}
while (m--) {
int l, r;
cin >> l >> r;
query.push_back(make_pair(l, r));
f.push_back(l);
f.push_back(r);
}
sort(f.begin(), f.end());
f.erase(unique(f.begin(), f.end()), f.end());
for (PII item : add) {
int p = find(item.first);
a[p] += item.second;
}
//求字首和
for (int i = 1; i <= f.size(); i++) {
s[i] =s[i-1]+ a[i];
}
for (PII item : query) {
int l = find(item.first);
int r = find(item.second);
cout << s[r] - s[l - 1] << endl;
}
return 0;
}
中綴表示式求值
#include<algorithm>
#include<iostream>
#include<unordered_map>
#include<stack>
#include<string>
using namespace std;
stack<int> num;
stack<char> op;
unordered_map<char, int> f{ {'(',0}, {'+',1},{'-',1},{'*',2},{'/',2} };
void eval() {
int b = num.top(); num.pop();
int a = num.top(); num.pop();
if (op.top() == '+')num.push(a + b);
else if (op.top() == '-')num.push(a - b);
else if (op.top() == '*')num.push(a*b);
else num.push(a / b);
op.pop();
}
int main() {
string s;
cin >> s;
for (int i = 0; i < s.size(); i++) {
char c = s[i];
if (isdigit(c)) {
int j = i, res = 0;
while (j < s.size() && isdigit(s[j]))res = res * 10 + s[j++] - '0';
num.push(res);
i = j - 1;
}
else if (c == '(')op.push(c);
else if (c == ')') {
while (op.top() != '(') {
eval();
}
op.pop();
}
else {
while (op.size() && f[op.top()] >= f[c])eval();
op.push(c);
}
}
while (op.size())eval();
cout << num.top();
}
雙指標演算法
解決最長連續不重複子序列
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int s[N], a[N];
int main(){
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int i, j,res=0;
for (i = 0, j = 0; i < n; i++) {
s[a[i]]++;
while (s[a[i]] > 1) {
s[a[j]]--;
j++;
}
res = max(res, i - j + 1);
}
cout << res;
}