1. 程式人生 > >藍橋杯複習整理

藍橋杯複習整理

//Dijkstra 最短路演算法
void dijkstra(int s, int t)
{
    memset(pre, -1, sizeof(pre));
    for(int i = 0; i < n; i++)
        dis[i] = Map[s][i], vis[i] = 0;
    dis[s] = 0;  vis[s] = 1; pre[s] = -1;
    int pos;
    for(int i = 1; i <= n; i++){
        int temp = INF, pos = 0;
        for(int j = 0; j < n; j++){
            if(!vis[j] && dis[j] < temp)
                temp = dis[j], pos = j;
        }
        vis[pos] = 1;
        for(int j = 0; j < n; j++)
            if(!vis[j] && Map[pos][j]+dis[pos] < dis[j]){
                dis[j] = min(dis[j], dis[pos]+Map[pos][j]); pre[j] = pos;
            }
    }
    return dis[t];
}


//Prim 演算法求最小生成樹
void Prim()
{
    memset(vis, 0, sizeof(vis));
    for(int i = 0; i < n; i++)
        dis[i] = Map[0][i];
    vis[0] = 1;
    int sum = 0;
    for(int i = 1; i < n; i++){
        int temp = INF, pos;
        for(int j = 0; j < n; j++)
            if(!vis[j] && dis[j] < temp)
                temp = dis[j], pos = j;
        if(temp == INF) return -1;
        vis[pos] = 1;
        sum += temp;
        for(int j = 0; j < n; j++)
            if(!vis[j] && dis[j] > Map[pos][j])
                dis[j] = Map[pos][j];
    }
    return sum;
}

//Floyd 演算法求最短路
void Floyd()
{
    for(int k = 0; k < n; k++){
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++)
                dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
        }
    }
}

//樹狀陣列
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000;
int bit[maxn], n;

int sum(int i)
{
    int s = 0;
    while(i > 0){
        s += bit[i];
        i -= (i&-i);
    }
    return s;
}

void add(int i, int x)
{
    while(i <= n){
        bit[i] += x;
        i += (i&-i);
    }
}

int main()
{
    memset(bit, 0, sizeof(bit));
    scanf("%d", &n);
    int num, a;
    for(int i = 1; i <= n; i++){
        scanf("%d", &num);
        add(i, num);
    }
    while(scanf("%d", &a) != EOF){
        cout << sum(a) << endl;
    }
    return 0;
}

//並查集
void init(int n)
{
    for(int i = 1; i <= n; i++)
        f[i] = i;
}
void unin(int a, int b)
{
    int fa = Find(a);
    int fb = Find(b);
    if(fa == fb)
        return ;
    else {
        if(a < b) f[b] = a;
        else      f[a] = b;
    }
}
int Find(int x)
{
    if(f[x] == x)
        return x;
    else
        return f[x] = Find(f[x]);
}

//優先佇列的建立
#include<bits/stdc++.h>
using namespace std;

struct Node{
    int x, y;
    bool operator < (const Node n) const{
        return x < n.x;
    }
};
priority_queue<Node> p_que;
priority_queue<int, vector<int>, less<int> > p1;
int main()
{
    Node node;
    int n;
    scanf("%d", &n);
    while(n--){
        scanf("%d %d", &node.x, &node.y);
        p_que.push(node);
    }
    while(!p_que.empty()){
        Node nn = p_que.top();
        cout << nn.x << " " << nn.y << endl;
        p_que.pop();
    }
    return 0;
}


//求最長上升子序列
#include<bits/stdc++.h>
using namespace std;
int main()
{
    memset(dp, 0, sizeof(0));
    int maxx = 0;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < i; j++){
            if(a[i] > a[j])
                dp[i] = max(dp[i], dp[j]+1);
        }
        maxx = max(maxx, dp[i]);
    }
    return 0;
}

//最長公共子序列
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int len1 = strlen(s1), len2 = strlen(s2);
    for(int i = 0; i < len1; i++){
        for(int j = 0; j < len2; j++){
            if(s1[i] == s2[j]) dp[i][j] = dp[i-1][j-1] + 1;
            else    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
        }
    }
    return 0;
}

//擴充套件歐幾里得
void ex_gcd(int a, int b, int &d, int &x, int &y)
{
    if(!b){
        d = a, x = 1, y = 0;
    }
    else {
        ex_gcd(b, a%b, d, y, x);
        y -= x*(a/b);
    }
}

//求點乘積
//求叉積
//如何判斷兩線段相交 每條線段的兩個交點都在另一條線段的兩側
//如何判斷點線上段上

//KMP
void getFail(char *P, int *f)
{
    int m = strlen(P);
    f[0] = 0, f[1] = 0;
    for(int i = 1; i < m; i++){
        int j = f[i];
        while(j && P[i] != P[j]) j = f[j];
        f[i+1] = P[i]==P[j] ? j+1 : 0;
    }
}

void Find(char *T, char *P, int *f)
{
    int n = strlen(T), m = strlen(P);
    getFail(P);
    int j = 0;
    for(int i = 0; i < n; i++){
        while(j && p[j] != T[i]) j = f[j];
        if(P[j] == T[i]) j++;
        if(j == m) cout << i-m+1;
    }
}

// Trie
void Insert(char *s)
{
    int len = strlen(s), root = 0;
    for(int i = 0; i < len; i++){
        int id = s[i]-'a';
        if(!Trie[root][id]) Trie[root][id] = tot++;
        root = Trie[root][id];
    }
    v[root] = true;
}

bool Find(char *s)
{
    int len = strlen(s), root = 0;
    for(int i = 0; i < len; i++){
        int id = s[i] - 'a';
        if(!Trie[root][id]) return false;
        root = Trie[root][id];
    }
    if(!v[root]) return false;
    else         return true;
}