複試機試準備

容易忘記的操作

擦除空格

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

附:

  1. bool isdigit(char c);<iostream>已經定義了
  2. 注意看清楚樣例的輸出格式,特別是沒有oj系統時。
  3. 注意調試cout出來的數記得註釋掉
  4. 遞歸返回條件順序容易錯,判斷先返回還是先處理再返回。見combination-sum-ii/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章