4 条题解

  • 0
    @ 2025-5-20 20:25:36

    算法一、DFS一号

    using namespace std;
    int n = 2, a[5], s;
    int dfs(int x, int sum) {
        if (x > n) return sum;
        int i = dfs(x + 1, sum);
        int j = dfs(x + 1, sum + a[x]);
        if (i == s) return i;
        if (j == s) return j;
        return -1;
    }
    int main() {
        for (int i = 1;i <= n; i++) scanf("%d", &a[i]), s += a[i];
        cout << dfs(1, 0) << endl;
        return 0;
    }
    

    算法二、DFS二号

    using namespace std;
    int a, b;
    int dfs(int x) {
        if (x <= 5) return x;
        return dfs(x / 2) + dfs(x - x / 2);
    } 
    int main() {
        scanf("%d%d", &a, &b);
        printf("%d\n", dfs(a) + dfs(b));
        return 0;
    }
    

    算法三、BFS

    using namespace std;
    int n = 2, a[5], s;
    queue<int> q;
    void bfs() {
        q.push(0);
        int c = 0;
        while (q.size()) {
            c++;
            int f = q.front(); q.pop();
            if (f == s) {printf("%d\n", f); exit(0);}
            q.push(f + a[c]);
            q.push(f);
        }
    }
    int main() {
        for (int i = 1;i <= n; i++) scanf("%d", &a[i]), s += a[i];
        bfs();
        return 0;
    }
    

    算法四、直接算咯

    using namespace std;
    int a, b;
    int main() {
        scanf("%d%d", &a, &b);
        printf("%d\n", a + b);
        return 0;
    }
    

    算法五、二分

    using namespace std;
    int a, b;
    int main() {
        scanf("%d%d", &a, &b);
        int l = 0, r = 200000000;
        while (l < r) {
            int mid = l + r >> 1;
            if (mid == a + b) {printf("%d\n", mid); return 0;}
            if (mid <  a + b) l = mid + 1;
            if (mid >  a + b) r = mid - 1;
        }
        cout << l << endl;
        return 0;
    }
    

    算法六、稍微有点暴力的枚举

    #include <bits/stdc++.h>
    using namespace std;
    int a, b;
    int main() {
        scanf("%d%d", &a, &b);
        for (int i = 0;i <= 200000000; i++) if (a + b == i) {printf("%d\n", i); break;}
        return 0;
    }
    

    算法七、最短路之dijkstra

    #include <bits/stdc++.h>
    using namespace std;
    int w[5][5], d[5], v[5];
    int n = 3;
    void dijkstra() {
        memset(d, 0x3f, sizeof d);
        memset(v, 0, sizeof v);
        d[1] = 0;
        for (int i = 1;i < n; i++) {
            int x = 0;
            for (int j = 1;j <= n; j++)
                if (!v[j] && (x == 0 || d[j] < d[x])) x = j;
            v[x] = 1;
            for (int y = 1;y <= n; y++)
                d[y] = min(d[y], d[x] + w[x][y]);
        }
    }
    int main() {
        int a, b; scanf("%d%d", &a, &b);
        memset(w, 0x3f, sizeof w);
        w[1][2] = a; w[2][3] = b;
        dijkstra();
        printf("%d\n", d[3]);
        return 0;
    }
    

    算法八、最短路之SPFA

    #include <bits/stdc++.h> using namespace std; int a, b, n = 3; int w[5][5], d[5], v[5]; queue q; void spfa() { memset(d, 0x3f, sizeof d); memset(v, 0, sizeof v); d[1] = 0, v[1] = 1; q.push(1); while (q.size()) { int x = q.front(); q.pop(); v[x] = 0; for (int i = 1;i <= n; i++) { // if (w[x][i] == 0x3f) continue; if (d[i] > d[x] + w[x][i]) { d[i] = d[x] + w[x][i]; if (!v[i]) q.push(i), v[i] = 1; } } } } int main() { scanf("%d%d", &a, &b); memset(w, 0x3f, sizeof w); w[1][2] = a; w[2][3] = b; spfa(); printf("%d\n", d[3]); return 0; }

    算法九、最短路之Floyd

    using namespace std;
    int d[5][5], n = 3;
    int main() {
        int a, b; scanf("%d%d", &a, &b);
        memset(d, 0x3f, sizeof d);
        d[1][2] = a; d[2][3] = b;
        for (int k = 1;k <= n; k++)
            for (int i = 1;i <= n; i++)
                for (int j = 1;j <= n; j++)
                    d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        printf("%d\n", d[1][3]);
        return 0;
    }
    

    算法十、高精

    #include<bits/stdc++.h> using namespace std; string a0, b0; int a[1005], b[1005]; int main(){ cin >> a0 >> b0; int l1 = a0.size(), l2 = b0.size(); for (int i = 0;i < l1; i++) a[l1 - i] = a0[i] - 48; for (int i = 0;i < l2; i++) b[l2 - i] = b0[i] - 48; l1 = max(l1, l2); for (int i = 1;i <= l1; i++) { a[i] += b[i]; if (a[i] > 9) a[i + 1] += 1, a[i] %= 10; } if (a[max(l1, l2) + 1] > 0) l1++; for (int i = l1;i >= 1; i--) printf("%d", a[i]); return 0; }

    算法十一、最小生成树之kruskal

    using namespace std;
    struct rec {
        int x, y, z;
    } edge[5];
     
    int fa[5], m = 2, ans = 0;
     
    int get(int x) {
        if (x == fa[x]) return x;
        return fa[x] = get(fa[x]);
    }
    int cmp(rec a, rec b) { return a.z < b.z; }
     
    int main() {
        int a, b; scanf("%d%d", &a, &b);
        edge[1] = (rec){1, 2, a};
        edge[2] = (rec){2, 3, b};
        for (int i = 1;i <= m + 1; i++) fa[i] = i;
        sort(edge + 1, edge + 1 + m, cmp);
        for (int i = 1;i <= m; i++) {
            int x = get(edge[i].x);
            int y = get(edge[i].y);
            if (x == y) continue;
            fa[x] = y;
            ans += edge[i].z;
        }
        printf("%d\n", ans);
        return 0;
    }
    

    算法十二、最小生成树之prim

    using namespace std;
    int w[5][5], d[5], n = 3, ans, v[5];
     
    void prim() {
        memset(d, 0x3f, sizeof d);
        memset(v, 0, sizeof v);
        d[1] = 0;
        for (int i = 1;i < n; i++) {
            int x = 0;
            for (int j = 1;j <= n; j++)
                if (!v[j] && (x == 0 || d[j] < d[x])) x = j;
            v[x] = 1;
            for (int y = 1;y <= n; y++)
                if (!v[y]) d[y] = min(d[y], w[x][y]);
        }
    }
    int main() {
        int a, b; scanf("%d%d", &a, &b);
        memset(w, 0x3f, sizeof w);
        w[1][2] = a; w[2][3] = b;
        prim();
        int ans = 0;
        for (int i = 2;i <= n; i++) ans += d[i];
        printf("%d\n", ans);
        return 0;
    }
    

    算法十三、前缀和

    using namespace std;
    int a[5], s[5];
    int main() {
        for (int i = 1;i <= 2; i++) scanf("%d", &a[i]), s[i] += a[i] + s[i - 1];
        printf("%d\n", s[2]);
        return 0;
    }
    

    算法十四、后缀和

    using namespace std;
    int a[5], s[5];
    int main() {
        for (int i = 2;i >= 1; i--) scanf("%d", &a[i]), s[i] += a[i] + s[i + 1];
        printf("%d\n", s[1]);
        return 0;
    }
    

    算法十五、位运算

    using namespace std;
    int add(int a, int b) {
        if (b == 0) return a;
        return add(a ^ b, (a & b) << 1);
    }
    int main() {
        int a, b; scanf("%d%d", &a, &b);
        printf("%d\n", add(a, b));
        return 0;
    }
    

    算法十六、树的直径——BFS

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 10;
     
    int head[maxn * 2],edge[maxn * 2],Next[maxn * 2],ver[maxn * 2];
    int vis[maxn], dist[maxn];
    int n = 3, p, q, d;
    int tot = 0;
    int maxd = 0;
     
    void add(int u,int v,int w) {
        ver[ ++ tot] = v,edge[tot] = w;
        Next[tot] = head[u],head[u] = tot;
    }
     
    int BFS(int u) {
        queue<int>Q;
        while(!Q.empty()) Q.pop();
        memset(vis, 0, sizeof vis);
        memset(dist, 0, sizeof dist);  
        Q.push(u);
        int x, max_num = 0;
        while(!Q.empty()) {
            x = Q.front();
            Q.pop();
            vis[x] = 1;
            for(int i = head[x]; i ; i = Next[i]) {
                int y = ver[i];
                if(vis[y]) continue;
                vis[y] = 1;
                dist[y] = dist[x] + edge[i];
                if(dist[y] > maxd) {
                    maxd = dist[y];
                    max_num = y;
                }
                Q.push(y);
            }
        }
        return max_num;
    }
    int main(void) {
        int a, b; scanf("%d%d", &a, &b);
        add(1, 2, a); add(2, 1, a);
        add(2, 3, b); add(3, 2, b);
        BFS(BFS(1));
        int ans = 0;
        for (int i = 1;i <= n; i++) ans = max(ans, dist[i]);
        printf("%d\n", ans);
        return 0;
    }
    

    算法十七、树的直径——DFS

    #include<bits/stdc++.h>
    #define maxn 100000
    using namespace std;
    struct node {
        int u, v, w, nex;
    } edge[2 * maxn + 10];
    int n = 3, d[maxn + 10], head[maxn + 10], f_num, cnt = 0, ans;
    inline void add(int x,int y,int z) {
        edge[++cnt].u = x;
        edge[cnt].v = y;
        edge[cnt].w = z;
        edge[cnt].nex = head[x];
        head[x] = cnt;
    }
    inline void dfs(int x, int fa) {
        if(ans < d[x]) {
            ans = d[x];
            f_num = x;
        }
        for (int i = head[x]; i != -1; i = edge[i].nex) {
            int j = edge[i].v;
            if (j == fa)continue;
            d[j] = d[x] + edge[i].w;    
            dfs(j, x);
        }
    }
    int main() {
        memset(head, -1, sizeof(head));
        int a, b; scanf("%d%d", &a, &b);
        add(1, 2, a); add(2, 1, a);
        add(2, 3, b); add(3, 2, b);
        dfs(1, 0);
        ans = 0;
        d[f_num] = 0;
        dfs(f_num, 0);
        for (int i = 1;i <= n; i++) ans = max(ans, d[i]);
        printf("%d", ans);
        return 0;
    }
    

    算法十八、树的直径——树形DP

    #include <bits/stdc++.h>
    using namespace std;
    int f[5], n = 3, cnt, h[5], ans, dis[5];
    struct edge {
        int to, next, vi;
    } e[5];
    void add(int u, int v, int w) {
        e[cnt].to= v;
        e[cnt].vi = w;
        e[cnt].next = h[u];
        h[u] = cnt++;
    }
    void dp(int u, int fa) {
        for (int i = h[u]; ~i; i = e[i].next) {
            int v = e[i].to;
            if (v == fa) continue;
            dp(v, u);
            ans = max(ans, dis[v] + dis[u] + e[i].vi);
            dis[u] = max(dis[u], dis[v] + e[i].vi);
        }
    }
    int main() {
        memset(h, -1, sizeof h);
        int a, b; scanf("%d%d", &a, &b);
        add(1, 2, a); add(2, 1, a);
        add(2, 3, b); add(3, 2, b);
        dp(1, 0);
        printf("%d\n", ans);
        return 0;
    }
    

    算法十九、网络流

    using namespace std;
    #define set(x) Set(x)
    #define REP(i,j,k) for (int i=(j),_end_=(k);i<=_end_;++i)
    #define DREP(i,j,k) for (int i=(j),_start_=(k);i>=_start_;--i)
    #define mp make_pair
    #define x first
    #define y second
    #define pb push_back
    template<typename T> inline bool chkmin(T &a,const T &b){ return a > b ? a = b, 1 : 0; }
    template<typename T> inline bool chkmax(T &a,const T &b){ return a < b ? a = b, 1 : 0; }
    typedef long long LL;
    typedef pair<int,int> node;
    const int dmax = 1010, oo = 0x3f3f3f3f;
    int n, m;
    int a[dmax][dmax] , ans;
    int d[dmax], e[dmax];
    priority_queue <node> q;
    inline bool operator >(node a,node b){ return a.y>b.y; }
    bool p[dmax];
    void Set(int x){ p[x] = 1; }
    void unset(int x){ p[x] = 0; }
    bool check(int x){ return x != 1 && x != n && !p[x] && e[x] > 0; }
    void preflow(){
        e[1] = oo;
        d[1] = n - 1;
        q.push(mp(1, n - 1));
        set(1);
        while (!q.empty()) {
            bool flag = 1;
            int k = q.top().x;
            q.pop(), unset(k);
            DREP(i, n, 1)
            if ((d[k] == d[i] + 1 || k == 1) && a[k][i] > 0){
                flag = 0;
                int t = min(a[k][i], e[k]);
                e[k] -= t;
                a[k][i] -= t;
                e[i] += t;
                a[i][k] += t;
                if (check(i)) {
                    q.push(mp(i, d[i]));
                    set(i);
                }
                if (e[k] == 0) break;
            }
            if (flag) {
                d[k] = oo;
                REP(i, 1, n)
                if (a[k][i] > 0) chkmin(d[k], d[i] + 1);
            }
            if (check(k)) {
                q.push(mp(k, d[k]));
                set(k);
            }
        }
        ans = e[n];
    }
    int main() {
        n = 2, m = 2;
        int x, y;
        scanf("%d%d", &x, &y);
        a[1][2] += x + y;
        preflow();
        printf("%d\n", ans);
        return 0;
    }
    

    算法二十、线段树

    #define l(x) tree[x].l
    #define r(x) tree[x].r
    #define sum(x) tree[x].sum
    #define add(x) tree[x].add
    using namespace std;
    struct SegmentTree {
        int l, r; //区间左右端点 
        long long sum, add; //sum 区间和  add 延迟标记 
    } tree[400010];
    int a[100010], n = 1, m = 2;
    void build (int p, int l, int r) {
        l(p) = l, r(p) = r;
        if(l == r) {sum(p) = a[l]; return;}
        int mid = l + r >> 1;
        build(p * 2, l, mid);
        build(p * 2 + 1, mid + 1, r);
        sum(p) = sum(p * 2) + sum(p * 2 + 1);
    }
    void spread(int p) {
        if(add(p)) { //节点p有标记 
            sum(p * 2) += add(p) * (r(p * 2) - l(p * 2) + 1); //更新左子节点信息 
            sum(p * 2 + 1) += add(p) * (r(p * 2 + 1) - l(p * 2 + 1) + 1); //更新右子节点
            add(p * 2) += add(p); //给左子节点打延迟标记 
            add(p * 2 + 1) += add(p); //给右子节点打延迟标记 
            add(p) = 0; //清除p的标记 
        }
    }
    void change(int p, int l, int r, int d) {
        if(l <= l(p) && r >= r(p)) { //完全覆盖 
            sum(p) += (long long) d * (r(p) - l(p) + 1); //更新节点信息 
            add(p) += d; //给节点打延迟标记 
            return;
        }
        spread(p); //下传延迟标记 
        int mid = l(p) + r(p) >> 1;
        if(l <= mid) change(p * 2, l, r, d);
        if(r > mid) change(p * 2 + 1, l, r, d);
        sum(p) = sum(p * 2) + sum(p * 2 + 1);
    }
    long long ask(int p, int l, int r) {
        if(l <= l(p) && r >= r(p)) return sum(p);
        spread(p);
        int mid = l(p) + r(p) >> 1;
        long long val = 0;
        if(l <= mid) val += ask(p * 2, l, r);
        if(r > mid) val += ask(p * 2 + 1, l, r);
        return val;
    }
    int main() {
        a[1] = 0;
        build(1, 1, n);
        while(m--) { 
            int d = 0;
            scanf("%d", &d);
            change(1, 1, 1, d);
        }
        printf("%lld\n", ask(1, 1, 1));
        return 0;
    }
    

    还有60多种,写不下了

    信息

    ID
    1
    时间
    1000ms
    内存
    128MiB
    难度
    3
    标签
    (无)
    递交数
    182
    已通过
    105
    上传者