容易忘記的操作
擦除空格
str.erase(remove(str.begin(), str.end(), ' '), str.end());
向上取整
printf("%.0f\n", ceil(a));
向下取整
printf("%.0f\n", floor(a));
算法
初始化素數數組
先將數組初始化爲true,然後從i開始每次的倍數改成false,記得i 的平方不能大於最大int 的最大表示範圍,即65536。在用另外一個int數組來記錄當前的素數。
void init() {
for (int i = 0; i < N; i++) isPrime[i] = true;
for (int i = 2; i < N; i++) {
if (!isPrime[i]) continue;
if (primepos > 10000) break;
Prime[++primepos] = i;
if (i >= 65536) continue;
for (int j = i*i; j >= 0 && j < N; j+=i) {
isPrime[j] = false;
}
}
}
質因數分解
先初始化質數數組,再通過for循環統計
int factorization(int num, int factors[]) {
int pos = 0;
int len = sqrt(num);
for (int i = 2; i <= len; i++) {
while (num != 0 && num % i == 0) {
factors[pos++] = i;
num /= i;
}
}
if (num > 1) factors[pos++] = num;
return pos;
}
最大公約數
int gcd(int num1, int num2) {
if (num2 == 0) return num1;
return gcd(num2, num1%num2);
}
最小公倍數
int lcm(int num1, int num2) {
int factor = gcd(num1, num2);
return num1/factor*num2; // 考慮到溢出的可能性,先除後乘
}
kmp算法
重點是next數組的建立,next數組是針對pattern的,初始化爲-1,相同則等於 next[i] = k,不同則等於k = next[k]。其次重點是循環遍歷的時候,注意將不同的時候,j = next[j]+1,因爲在i的for循環中i已經自動+1了。
void get_next(int* next, char* p, int n) {
next[0] = -1;
int k = -1, j = 0;
while (j < n) {
if (k == -1 || p[j] == p[k]) {
k++;
j++;
next[j] = k;
} else {
k = next[k];
}
}
}
for (i = 0; i < n; i++) {
if (t[i] == p[j]) j++;
else j = next[j]+1;
if (j == m) {
count++;
j = next[j];
}
}
第k大的數
找第k大的數,利用快排的思想(swap可以用algorithm裏面的)
int find(vector<int>& nums, int first, int last, int k) {
if (first > last) return -1;
else if (first == last) return nums[first];
int key = nums[first];
for (int i = last; i > first; i--) {
if (nums[i] >= key) {
swap(nums, last, i);
last--;
}
}
swap(nums[first], nums[last]);
if (k == nums.size()-last) return nums[last];
else if (k > nums.size()-last) return find(nums, first, last-1, k);
else return find(nums, last+1, nums.size()-1, k);
}
數學表達式的計算
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <cctype>
using namespace std;
double calculate(string str);
double parseNum(string str, int& i);
double parseExpr(string str, int& i);
int main() {
string str;
cin >> str;
double res = calculate(str);
printf("%0.0f\n", res);
return 0;
}
double calculate(string str) {
cout << str << endl;
str.erase(remove(str.begin(), str.end(), ' '), str.end());
int i = 0;
cout << str << endl;
double res = parseExpr(str, i);
return res;
}
double parseExpr(string str, int& i) {
stack<double> sta;
char op = '+';
double tmp = 0;
for (; i < str.size() && str[i] != ')'; i++) {
double num = 0;
if (str[i] == '(') tmp = parseExpr(str, i);
else tmp = parseNum(str, i);
switch(op) {
case '-':
sta.push(-tmp);
break;
case '+':
sta.push(tmp);
break;
case '*':
num = sta.top() * tmp;
sta.pop();
sta.push(num);
break;
case '/':
num = sta.top() / tmp;
sta.pop();
sta.push(num);
break;
}
op = str[i];
tmp = 0;
}
double res = 0;
while (!sta.empty()) {
res += sta.top();
sta.pop();
}
return res;
}
double parseNum(string str, int& i) {
double res = 0;
for (; i< str.size(); i++) {
if (isdigit(str[i])) res = res*10 + str[i] - '0';
}
return res;
}
排列組合
關鍵點:j -> i,
void init() {
Cmn[0][1] = Cmn[1][1] = 1;
for (int i = 1; i < 21; i++) {
Cmn[0][i] = 1;
for(int j=1;j<=i;j++)
if(i==j) Cmn[j][i]=1;
else Cmn[j][i]=Cmn[j-1][i-1]+Cmn[j][i-1]; //
}
return;
}
附:
bool isdigit(char c);
在<iostream>
已經定義了- 注意看清楚樣例的輸出格式,特別是沒有oj系統時。
- 注意調試cout出來的數記得註釋掉
- 遞歸返回條件順序容易錯,判斷先返回還是先處理再返回。見combination-sum-ii/