藍橋杯複習整理
阿新 • • 發佈:2018-12-13
//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; }