1. 程式人生 > >ACM常用介面整理 (模板)

ACM常用介面整理 (模板)

1. 結構體排序

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
#define INF 1e7
#define N 100010
#define M 100010

struct Node {
    int x, h;
    int id, ans;
}nodes[N];

bool comp1(Node a, Node b) {
    return a.x < b.x;
    //<升序,>降序,a.x以x排序
} bool comp2(Node a, Node b) { return a.id < b.id; //<升序,>降序,a.id以a排序 } int main(){ sort(nodes+1, nodes+n+1, comp1); // 按照x值排序 return 0; }

2. 二分查詢左邊界

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std
; #define INF 1e7 #define N 100010 #define M 100010 int ans[10] = {1, 2, 6, 6, 6, 6, 7, 8, 9, 10}; //二分查詢左邊界或 < value的最大值 int binary_search(int l, int r, int value) { printf("%d,%d\n", l, r); if (l == r) return l; int mid = (l + r) / 2; if (value <= ans[mid]) return binary_search(l, mid, value); return
binary_search(mid + 1, r, value); } int main() { for (int i = 1; i <= 13; i++) { int id = binary_search(0, 9, i); printf("%d==========%d\n", i, id); } return 0; }

3. C++ 常用演算法模板

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
#define INF 0x0f0f0f
#define N 100010
#define M 100010

////////////////////////////////  雜項 //////////////////////////////////
int max(int a, int b) { return a > b ? a : b; }

int min(int a, int b) { return a < b ? a : b; }

////////////////////////////////  最大公約數 //////////////////////////////////
int gcd(int a, int b) {
    if (a % b == 0) return b;
    return gcd(b, a % b);
}

////////////////////////////////  最小公倍數 //////////////////////////////////
int lcm(int a, int b) {
    return a / gcd(a, b) * b;
}

////////////////////////////////  不重複全排列 //////////////////////////////////
int n, record[N], use[N], value[N];

void unrepeat_permutation(int l) {
    if (l == n) {
        printf("%d", record[0]);
        for (int i = 1; i < n; i++) {
            printf(" %d", record[i]);
        }
        printf("\n");
        return;
    }
    for (int i = 0; i < n; i++) {
        if (use[i]) {
            use[i]--;
            record[l] = value[i];
            unrepeat_permutation(l + 1);
            use[i]++;
        }
    }
}

////////////////////////////////  不重複組合 //////////////////////////////////
//int n, record[N], use[N], value[N];
void unrepeat_combination(int l, int offset) {
    for (int i = 0; i < l; i++) {
        printf(" %d", record[i]);
        if (i != l - 1) printf(" ");
    }
    if (l) printf("\n");
    for (int i = offset; i < n; i++) {
        if (use[i]) {
            use[i]--;
            record[l] = value[i];
            unrepeat_combination(l + 1, i);
            use[i]++;
        }
    }
}

////////////////////////////////  線段樹 //////////////////////////////////
int tree[4 * N];

void update(int n) {
    tree[n] = tree[n << 1] + tree[n << 1 | 1];
}

void build_tree(int left, int right, int n) {
    if (left == right) {
        tree[n] = value[right];
        return;
    }
    int mid = (left + right) >> 1;
    build_tree(left, mid, n << 1);
    build_tree(mid + 1, right, n << 1 | 1);
    update(n);
}

// 單點更新操作; left一般恆等於1,right一般恆等於n,n一般恆等於1
void add(int node_idx, int v, int left, int right, int n) {
    if (left == right) {
        tree[n] = v;
        return;
    }
    int mid = (left + right) >> 1;
    if (node_idx <= mid) {
        add(node_idx, v, left, mid, n << 1);
    } else {
        add(node_idx, v, mid + 1, right, n << 1 | 1);
    }
    update(n);
}

// l為要查詢的區間左邊界; left一般恆等於1,right一般恆等於n,n一般恆等於1
int query(int l, int r, int left, int right, int n) {
    if (l <= left && r >= right) return tree[n];
    int mid = (left + right) >> 1;
    int sum = 0;
    if (l <= mid) {
        sum += query(l, r, left, mid, n << 1);
    }
    if (r > mid) {
        sum += query(l, r, mid + 1, right, n << 1 | 1);
    }
    return sum;
}

////////////////////////////////  最大子串和 //////////////////////////////////
int max_sub_array(int a[]) {
    int _max = a[0], tmp = a[0];
    for (int i = 1; i < n; i++) {
        if (tmp > 0) tmp += a[i];
        else tmp = a[i];
        _max = max(_max, tmp);
    }
    return _max;
}

////////////////////////////////  最小生成樹Prim //////////////////////////////////
int prim(int cost[][N]) {
    // tmp[k] 儲存到達第k個節點的最小邊
    int tmp[N], vis[N];
    int min_path = 0;
    for (int i = 0; i < n; i++) {
        tmp[i] = cost[0][i];
        vis[i] = 0;
    }
    vis[0] = 1;
    for (int i = 1; i < n; i++) {
        int edge = INF, k = 0;
        for (int j = 1; j < n; j++) {
            if (vis[j] == 0 && edge > tmp[j]) {
                edge = tmp[j];
                k = j;
            }
        }
        if (edge == INF) return -1;
        min_path += edge;
        vis[k] = 1;
        for (int j = 1; j < n; j++) {
            if (vis[j] == 0 && tmp[j] > cost[k][j]) {
                tmp[j] = cost[k][j];
            }
        }
    }
    return min_path;
}

////////////////////////////////  並查集 //////////////////////////////////
int set_id[N], sum = 0;

void make_set() {
    for (int i = 0; i < n; i++) {
        set_id[i] = i;
    }
}

int find_set_id(int x) {
    if (set_id[x] != x)
        set_id[x] = find_set_id(set_id[x]);
    return set_id[x];
}

void _union(int x, int y) {
    int set_id1 = find_set_id(x);
    int set_id2 = find_set_id(y);
    if (set_id1 != set_id2) {
        set_id[set_id2] = set_id1;
        sum++;
    }

}

////////////////////////////////  高效篩素數 //////////////////////////////////
int prime[N];

void get_prime() {
    int offset = 0, vis[N];
    memset(vis, 0, sizeof(vis));
    for (int i = 2; i < N; i++) {
        if (vis[i] == 0) {
            prime[offset++] = i;
        }
        for (int j = 0; j < offset && prime[j] * i < N; j++) {
            vis[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}


int main() {
    int n, m;
    freopen("../test.txt", "r", stdin);
    while (~scanf("%d%d", &n, &m)) {
        printf("%d %d\n", n, m);
    }
    return 0;
}