1. 程式人生 > 其它 >[acwing][模板]基本演算法模板

[acwing][模板]基本演算法模板

快排

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;
}