Bootstrap

数据结构(相关练习题代码)

980 (二叉树的层次遍历)

#include <iostream>
#include <queue>
using namespace std;

const int N = 100010;
char w[N];
queue<int> q;

void create(int i) {
    cin >> w[i];
    if (w[i] == '#') return;
    create(2 * i);
    create(2 * i + 1);
}

void print() {
    q.push(1);
    while (q.size()) {
        int i = q.front();
        cout << w[i];
        q.pop();
        if (w[2 * i] != '#') q.push(2 * i);
        if (w[2 * i + 1] != '#') q.push(2 * i + 1);
    }
}

int main() {
    create(1);
    print();
    return 0;
}

981 (树的棵树)

#include <iostream>
using namespace std;

const int N = 100010;
char w[N];
int cnt = 1, ans = 0;

void create(int i) {
    cin >> w[i];
    if (w[i] == '#') return;
    create(2 * i);
    create(2 * i + 1);
}

void search(int i, int cnt) {
    if (w[i] == '#') return;
    search(2 * i, 0);
    search(2 * i + 1, cnt + 1);
    ans = max(ans, cnt);
}

int main() {
    create(1);
    search(1, 0);
    cout << ans;
    return 0;
}

982 (普通树的度)

#include <iostream>
using namespace std;

const int N = 100010;
char w[N];
int cnt = 1, ans = 0;

void create(int i) {
    cin >> w[i];
    if (w[i] == '#') return;
    create(2 * i);
    create(2 * i + 1);
}

void search(int i, int cnt) {
    if (w[i] == '#') return;
    ans = max(ans, cnt);
    search(2 * i, 1);
    search(2 * i + 1, cnt + 1);
}

int main() {
    create(1);
    search(1, 1);
    if (w[3] != '#') cout << "ERROR";
    else cout << ans;
    return 0;
}

984 (中序,先序得后序)

#include <iostream>
#include <string>
using namespace std;

void dfs(string x, string y) {
    if (y.size() == 0) return;
    int i = x.find(y[0]);
    dfs(x.substr(0, i), y.substr(1, i));
    dfs(x.substr(i + 1), y.substr(i + 1));
    cout << y[0];
}

int main() {
    string a, b;
    while (cin >> a >> b) {
        dfs(a, b);
    }
    return 0;
}

986 (哈夫曼译码)

#include <iostream>
#include <string>
using namespace std;

int t = 0;

void haf(string s) {
    if (s == "0001") cout << "a";
    if (s == "10") cout << "b";
    if (s == "1110") cout << "c";
    if (s == "1111") cout << "d";
    if (s == "110") cout << "e";
    if (s == "01") cout << "f";
    if (s == "0000") cout << "g";
    if (s == "001") cout << "h";
}

int main() {
    string a, b;
    cin >> a;
    while (t < a.size()) {
        b += a[t];
        if (a[t] != b[0] || b.size() == 4) {
            haf(b);
            b.clear();
        }
        t++;
    }
    return 0;
}

987 (是否为完全二叉树)

#include <iostream>
using namespace std;

const int N = 100010;
char w[N];
int ans = 1;

bool create(int i) {
    cin >> w[i];
    if (w[i] == '#') return 0;
    int cnt = 0;
    if (create(2 * i)) cnt++;
    if (create(2 * i + 1)) cnt++;
    if (cnt == 1) ans = 0;
    return 1;
}

int main() {
    create(1);
    if (ans) cout << "Y";
    else cout << "N";
    return 0;
}

1010 (折半查找)

#include <iostream>
using namespace std;

const int N = 100010;
int a[N], n, x;

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    cin >> x;
    int l = 0, r = n - 1, cnt = 0;
    while (l <= r) {
        cnt++;
        int mid = (l + r) / 2;
        if (a[mid] == x) {
            l = mid;
            break;
        }
        if (a[mid] < x) l = mid + 1;
        else r = mid - 1;
    }
    if (a[l] != x) cout << -1 << endl;
    else cout << l << endl;
    cout << cnt;
    return 0;
}

1011 (二叉排序树的实现和查找)

#include <iostream>
#include <algorithm>
using namespace std;

#define N 100001

int main() {
    int n, a[N], x, cont = 0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    sort(a, a + n);
    cin >> x;
    int l = 0, r = n - 1, mid;
    while (l <= r) {
        cont++;
        mid = (l + r) / 2;
        if (a[mid] == x) break;
        if (a[mid] > x) r = mid - 1;
        else l = mid + 1;
    }
    if (a[mid] != x) cout << -1;
    else cout << cont;
    return 0;
}

1012 (哈希表(链地址))

#include <iostream>
using namespace std;

int main() {
    int m, n, key, a[100][100], b[100] = {0}, i, flag = 0;
    cin >> m >> n;
    for (i = 0; i < n; i++) {
        cin >> key;
        a[key % m][b[key % m]++] = key;
    }
    cin >> key;
    for (i = 0; i < n; i++) {
        if (a[key % m][i] == key) {
            flag = 1;
            cout << key % m << "," << i + 1;
            break;
        }
    }
    if (flag == 0) cout << "-1";
    return 0;
}

1013 (哈希表(开放地址))

#include <iostream>
using namespace std;

int main() {
    int m, n, key, a[100][100], i, flag = 0;
    cin >> m >> n;
    for (i = 0; i < n; i++) {
        cin >> key;
        a[key % m][i] = key;
    }
    cin >> key;
    for (i = 0; i < n; i++) {
        if (a[key % m][i] == key) {
            flag = 1;
            cout << key % m << "," << i + 1;
            break;
        }
    }
    if (flag == 0) cout << "-1";
    return 0;
}

1014 (冒泡排序,第一趟)

#include <iostream>
using namespace std;

int main() {
    int n, a[1000], i, t;
    cin >> n;
    for (i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (i = 0; i < n - 1; i++) {
        if (a[i] > a[i + 1]) swap(a[i], a[i + 1]);
    }
    for (i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    return 0;
}

1015 (堆排序算法,一趟)

#include <iostream>
using namespace std;

const int N = 100010;
int n, h[N], cnt;

void down(int u) {
    int t = u;
    if (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2;
    if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
    if (u != t) {
        swap(h[u], h[t]);
        down(t);
    }
}

int main() {
    scanf("%d", &n);
    cnt = n;
    for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
    for (int i = n / 2; i; i--) down(i);
    for (int i = 1; i <= n; i++) cout << h[i] << " ";
    return 0;
}

1016 (插入排序算法)

#include <iostream>
using namespace std;

const int N = 100010;
int n, a[N];

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    if (a[2] <= a[1]) swap(a[1], a[2]);
    for (int i = 1; i <= n; i++) cout << a[i] << ' ';
    return 0;
}

1053 (指定结点的度)

#include <iostream>
using namespace std;

const int N = 100010;
char w[N], ch;

void create(int i) {
    cin >> w[i];
    if (w[i] == '#') return;
    create(2 * i);
    create(2 * i + 1);
}

void print(int i) {
    if (w[i] == '#') return;
    if (w[i] == ch) {
        int cnt = 0;
        if (w[2 * i] != '#') cnt++;
        if (w[2 * i + 1] != '#') cnt++;
        cout << cnt;
    } else {
        print(2 * i);
        print(2 * i + 1);
    }
}

int main() {
    create(1);
    cin >> ch;
    print(1);
    return 0;
}

1055 (邻接矩阵到邻接表)

#include <iostream>
using namespace std;

int main() {
    int n, a[100][100], i, j;
    cin >> n;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            cin >> a[i][j];
        }
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if (a[i][j] == 1) cout << j;
        }
        cout << "\n";
    }
    return 0;
}

1056 (邻接表到邻接矩阵)

#include <iostream>
using namespace std;

int main() {
    int n, a[100][100] = {0}, i, j;
    cin >> n;
    char ch;
    getchar();
    for (i = 0; i < n; i++) {
        while (1) {
            scanf("%c", &ch);
            if (ch == '\n') break;
            a[i][ch - '0'] = 1;
        }
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            cout << a[i][j];
        }
        cout << "\n";
    }
    return 0;
}

1057 (有向图的出度计算)

#include <iostream>
using namespace std;

const int N = 110;
int a[N];

int main() {
    int n, e;
    cin >> n >> e;
    while (e--) {
        int u, v;
        cin >> u >> v;
        a[u]++;
    }
    for (int i = 0; i < n; i++) cout << a[i] << endl;
    return 0;
}

1060 (无向图的最大度计算)

#include <iostream>
using namespace std;

const int N = 110;
int g[N][N];
int t[N];

int main() {
    int n, mx = 0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> g[i][j];
            if (g[i][j] == 1) {
                t[i]++;
                t[j]++;
                mx = max(mx, max(t[i], t[j]));
            }
        }
    }
    cout << mx / 2 << endl;
    for (int i = 0; i < n; i++) {
        if (t[i] == mx) cout << i;
    }
    return 0;
}

1062 (有向图的边存在判断)

#include <iostream>
using namespace std;

const int N = 110;
int g[N][N];

int main() {
    int n, u, v;
    cin >> n >> u >> v;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> g[i][j];
        }
    }
    if (g[u][v] == 1) cout << "yes";
    else cout << "no";
    return 0;
}

1065 (无向图的连通分量计算)

#include <iostream>
using namespace std;

const int N = 110;
int g[N][N];
bool st[N];
int n;

void dfs(int u) {
    st[u] = 1;
    for (int i = 0; i < n; i++) {
        if (g[u][i] == 1 && !st[i]) dfs(i);
    }
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> g[i][j];
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        if (st[i]) continue;
        cnt++;
        dfs(i);
    }
    cout << cnt;
    return 0;
}

1067 (有向图的邻接表储存强连通判断)

#include <iostream>
using namespace std;

int main() {
    int n, e, a[100][100], b[100] = {0}, i, flag = 0;
    cin >> n >> e;
    for (i = 0; i < e; i++) {
        cin >> a[i][0] >> a[i][1];
    }
    for (i = 0; i < e; i++) {
        b[a[i][0]]++;
    }
    for (i = 0; i < n; i++) {
        if (b[i] == 0) flag = 1;
    }
    if (flag == 0) cout << "yes";
    else cout << "no";
    return 0;
}

1068 (图的深度优先搜索)

#include <iostream>
#include <string>
using namespace std;

const int N = 110;
int g[N][N];
bool st[N];
int n;
string s;

void dfs(int u) {
    cout << s[u];
    st[u] = 1;
    for (int i = 0; i < n; i++) {
        if (st[i] || g[u][i] == 0) continue;
        dfs(i);
    }
}

int main() {
    cin >> n >> s;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> g[i][j];
        }
    }
    string ch;
    cin >> ch;
    int t = s.find(ch);
    dfs(t);
    return 0;
}

1069 (图的广度优先搜索)

#include <iostream>
#include <string>
#include <queue>
using namespace std;

const int N = 110;
int g[N][N];
bool st[N];
int n;
string s;

void bfs(int u) {
    queue<int> q;
    q.push(u);
    while (q.size()) {
        int t = q.front();
        q.pop();
        if (st[t]) continue;
        st[t] = 1;
        cout << s[t];
        for (int i = 0; i < n; i++) {
            if (g[t][i] == 0 || st[i]) continue;
            q.push(i);
        }
    }
}

int main() {
    cin >> n >> s;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> g[i][j];
        }
    }
    string ch;
    cin >> ch;
    int t = s.find(ch);
    bfs(t);
    return 0;
}

1070 (邻接矩阵存储简单路径)

#include <iostream>
using namespace std;

const int N = 110;
int g[N][N], p[N];
bool st[N];
int n, u, v;

void dfs(int x, int t) {
    p[t] = x;
    if (x == v) {
        for (int i = 0; i < t; i++) cout << p[i];
        cout << v << endl;
        return;
    }
    st[x] = 1;
    for (int i = 0; i < n; i++) {
        if (st[i] || g[x][i] == 0) continue;
        dfs(i, t + 1);
    }
    st[x] = 0;
}

int main() {
    cin >> n >> u >> v;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> g[i][j];
        }
    }
    dfs(u, 0);
    return 0;
}

1075 (prim 算法,最小生成树)

#include <iostream>
#include <cstring>
#include <ios>
#include <iomanip>
using namespace std;

char Data[1002];
int visit[1002], minn[1002], n;
int vertexs[1002][1002];

void Prim(int k) {
    minn[k] = 0;
    for (int i = 0; i < n; i++) {
        int k = -1;
        for (int j = 0; j < n; j++) {
            if (!visit[j] && (k == -1 || minn[k] > minn[j])) k = j;
        }
        visit[k] = 1;
        if (k != 0) {
            for (int j = 0; j < n; j++) {
                if (visit[j] && vertexs[j][k] == minn[k]) {
                    cout << '(' << Data[j] << ',' << Data[k] << ')';
                }
            }
        }
        for (int j = 0; j < n; j++) {
            if (!visit[j] && vertexs[k][j] < minn[j]) {
                minn[j] = vertexs[k][j];
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int m, i, z;
    char x, y;
    memset(minn, 9999, sizeof(minn));
    memset(vertexs, 9999, sizeof(vertexs));
    cin >> n >> m;
    for (i = 0; i < n; i++) {
        cin >> Data[i];
    }
    for (i = 0; i < m; i++) {
        cin >> x >> y >> z;
        vertexs[x - 'A'][y - 'A'] = z;
        vertexs[y - 'A'][x - 'A'] = z;
    }
    Prim(0);
    return 0;
}

1076 (判断有向图是否存在回路)

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

#define int long long 

int n, m, cnt;
char a[1010];
int g[30][30], d[30];
vector<int> v;
queue<int> q;

bool topsort() {
    for (int i = 1; i <= n; i++) {
        if (!d[a[i] - 'A']) q.push(a[i] - 'A');
    }
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        cnt++;
        for (int i = 1; i <= n; i++) {
            if (g[x][a[i] - 'A']) {
                if (!(--d[a[i] - 'A'])) {
                    q.push(a[i] - 'A');
                }
            }
        }
    }
    return cnt < n;
}

signed main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    while (m--) {
        char u, v;
        cin >> u >> v;
        g[u - 'A'][v - 'A'] = 1;
        d[v - 'A']++;
    }
    if (topsort()) cout << "yes";
    else cout << "no";
    return 0;
}

1077 (平衡二叉树的判断)

#include <iostream>
#include <cmath>
using namespace std;

int ans = 1;

struct {
    int l, r;
} a[102];

int create() {
    char ch;
    cin >> ch;
    if (ch == '#') return ch;
    a[ch].l = create();
    a[ch].r = create();
    return ch;
}

int f(char ch) {
    if (ch == '#') return 0;
    else return (1 + max(f(a[ch].l), f(a[ch].r)));
}

void dfs(char ch) {
    if (ch == '#') return;
    int l = f(a[ch].l);
    int r = f(a[ch].r);
    int h = abs(l - r); // 取绝对值
    if (h > 1) ans = 0;
    return;
}

int main() {
    create();
    dfs('A');
    cout << ((ans == 1) ? "yes!" : "no!");
    return 0;
}

1098 (堆的判断)

#include <iostream>
using namespace std;

const int N = 510;
int w[N];

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> w[i];
    }
    for (int i = 1; i <= n; i++) {
        if ((w[i] > w[2 * i] && 2 * i <= n) || (w[i] > w[2 * i + 1] && 2 * i + 1 <= n)) {
            cout << "No";
            return 0;
        }
    }
    cout << "Yes";
    return 0;
}

1099 (希尔排序算法的实现)

#include <iostream>
using namespace std;

const int N = 510;
int g[N], n;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> g[i];
    }
    int gap = n / 2;
    for (int i = 1; i <= gap; i++) {
        if (g[i] > g[i + gap]) {
            swap(g[i], g[i + gap]);
        }
    }
    for (int i = 1; i <= n; i++) {
        cout << g[i] << ' ';
    }
    return 0;
}

1105 (交换二叉树的孩子结点)

#include <iostream>
using namespace std;

const int N = 100010;
char w[N];

void create(int i) {
    cin >> w[i];
    if (w[i] == '#') return;
    create(2 * i + 1);
    create(2 * i);
}

void print1(int i) {
    if (w[2 * i] != '#') print1(2 * i);
    cout << w[i];
    if (w[2 * i + 1] != '#') print1(2 * i + 1);
}

void print2(int i) {
    cout << w[i];
    if (w[2 * i] != '#') print2(2 * i);
    if (w[2 * i + 1] != '#') print2(2 * i + 1);
}

signed main() {
    create(1);
    print1(1);
    cout << endl;
    print2(1);
    return 0;
}

;