zoukankan      html  css  js  c++  java
  • 退役题目集合

    2019年07月25日23:56:32

      https://www.hackerrank.com/challenges/sam-and-substrings/editorial

           求一个数字字符串所有子串数字之和,dp[i]表示以第i个字符结尾的总和,列举所有出来可得到递推公式。

    2018-05-08 16:56:08

    https://csacademy.com/contest/archive/task/swap_pairing/statement/

    题目意思是问,给定一个数组,每个数字都精确出现了两次。每一个操作可以交换相邻的两个数字。

    要求目标是相同的数字挨在一起,求最小的操作次数。

    贪心的做法是最左边的数字肯定不要动,让最右边的数字靠过来。这样最优。然后就是第一次先匹配a[1], 然后再匹配a[2]......这样。

    统计的时候用树状数组维护一下就好

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <string>
    #include <iostream>
    #include <assert.h>
    #include <map>
    
    using namespace std;
    
    const int maxn = 1e5 + 20;
    
    int c[maxn];
    int lowbit(int pos) {
        return pos & (-pos);
    }
    
    int ask(int pos) {
        int ans = 0;
        while (pos > 0) {
            ans += c[pos];
            pos -= lowbit(pos);
        }
        return ans;
    }
    
    void update(int pos, int val) {
        while (pos < maxn) {
            c[pos] += val;
            pos += lowbit(pos);
        }
    }
    
    int a[maxn];
    bool need[maxn];
    
    map<int, int> mp;
    
    void work() {
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i];
        }
        for (int i = n; i >= 1; --i) {
            if (mp.count(a[i]) == 0) {
                mp[a[i]] = i;
            } else need[i] = true;
        }
        long long int ans = 0;
        for (int i = 1; i <= n; ++i) {
            if (!need[i]) continue;
            ans += mp[a[i]] - i - 1;
            ans -= ask(mp[a[i]]) - ask(i - 1);
            update(mp[a[i]], 1);
        }
        cout << ans << endl;
    }
    
    
    int main() {
        // freopen("data.txt", "r", stdin);
        work();
        return 0;
    }
    View Code

    A - 一棵简单的线段树

    被卡了返回vector<long long int>

    又暂时学不会返回引用,惨。。cpp白学

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6 + 2;
    const long long int inf = (long long int) 1e18;
    const int oo = (int) 1e9;
    
    struct segTree {
        int L, R;
        long long int sum;
        int mx, mi;
    } seg[maxn << 2];
    
    int root;
    
    int build(int L, int R) {
        int now = ++root;
        seg[now].sum = 0;
        seg[now].mx = -oo;
        seg[now].mi = oo;
        if (L == R) {
            seg[now].sum = seg[now].mi = seg[now].mx = 0;
            return now;
        }
        int mid = (L + R) >> 1;
        seg[now].L = build(L, mid);
        seg[now].R = build(mid + 1, R);
    
        seg[now].sum = seg[seg[now].L].sum + seg[seg[now].R].sum;
        seg[now].mx = max(seg[seg[now].L].mx, seg[seg[now].R].mx);
        seg[now].mi = min(seg[seg[now].L].mi, seg[seg[now].R].mi);
    
        return now;
    }
    
    void update(int pos, int val, int L, int R, int cur) {
        if (L == R) {
            seg[cur].mx = seg[cur].mi = seg[cur].sum = val;
            return;
        }
        int mid = (L + R) >> 1;
        if (pos <= mid) {
            update(pos, val, L, mid, seg[cur].L);
        } else update(pos, val, mid + 1, R, seg[cur].R);
    
        int lson = seg[cur].L, rson = seg[cur].R;
    
        seg[cur].mx = max(seg[lson].mx, seg[rson].mx);
        seg[cur].mi = min(seg[lson].mi, seg[rson].mi);
        seg[cur].sum = seg[lson].sum + seg[rson].sum;
    }
    
    vector<long long int> ask(int be, int en, int L, int R, int cur) {
    
        // cout << "now" << endl;
        // cout << L << " " << R << endl;
        if (L >= be && R <= en) {
            vector<long long int> vc;
            vc.push_back(seg[cur].sum);
            vc.push_back(seg[cur].mx);
            vc.push_back(seg[cur].mi);
            return vc;
        }
        // cout << L << " " << R << endl;
        int mid = (L + R) >> 1;
    
        vector<long long int> ans;
        for (int i = 0; i < 3; ++i) ans.push_back(0);
        ans[1] = -inf;
        ans[2] = inf;
    
        if (be <= mid) {
            vector<long long int> res = ask(be, en, L, mid, seg[cur].L);
            // cout << "left" << " " << L << " " << R << endl;
            // for (int i = 0; i < 3; ++i) {
            //     cout << res[i] << " ";
            // }
            // cout << endl;
            ans[0] += res[0];
            ans[1] = max(ans[1], res[1]);
            ans[2] = min(ans[2], res[2]);
        }
        if (en >= mid + 1) {
            vector<long long int> res = ask(be, en, mid + 1, R, seg[cur].R);
            // cout << "right" << " " << L << " " << R << endl;
            // for (int i = 0; i < 3; ++i) {
            //     cout << res[i] << " ";
            // }
            // cout << endl;
            // cout << "vimi" << " " << L << " " << R << endl;
            // for (int i = 0; i < 3; ++i) {
            //     cout << ans[i] << " ";
            // }
            // cout << endl;
            ans[0] += res[0];
            ans[1] = max(ans[1], res[1]);
            ans[2] = min(ans[2], res[2]);
        }
        return ans;
    }
    
    void work() {
        int n;
        scanf("%d", &n);
        build(1, n);
        int q;
        scanf("%d", &q);
        while (q--) {
            int op, one, two;
            scanf("%d%d%d", &op, &one, &two);
            if (op == 0) {
                update(one, two, 1, n, 1);
            } else {
                vector<long long int> vc = ask(one, two, 1, n, 1);
                // cout << "test " << vc[0] << " " << vc[1] << " " << vc[2] << endl;
                printf("%lld
    ", vc[0] - vc[1] - vc[2]);
            }
        }
    }
    
    int main() {
        // freopen("data.txt", "r", stdin);
        work();
        return 0;
    }
    TLE 5

    改了一改就行了

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6 + 2;
    const long long int inf = (long long int) 1e18;
    const int oo = (int) 1e9;
    
    struct segTree {
        int L, R;
        long long int sum;
        int mx, mi;
    } seg[maxn << 3];
    
    int root;
    
    int build(int L, int R) {
        int now = ++root;
        if (L == R) {
            seg[now].sum = seg[now].mi = seg[now].mx = 0;
            return now;
        }
        int mid = (L + R) >> 1;
        seg[now].L = build(L, mid);
        seg[now].R = build(mid + 1, R);
    
        seg[now].sum = seg[seg[now].L].sum + seg[seg[now].R].sum;
        seg[now].mx = max(seg[seg[now].L].mx, seg[seg[now].R].mx);
        seg[now].mi = min(seg[seg[now].L].mi, seg[seg[now].R].mi);
    
        return now;
    }
    
    void update(int pos, int val, int L, int R, int cur) {
        if (L == R) {
            seg[cur].mx = seg[cur].mi = seg[cur].sum = val;
            return;
        }
        int mid = (L + R) >> 1;
        if (pos <= mid) {
            update(pos, val, L, mid, seg[cur].L);
        } else update(pos, val, mid + 1, R, seg[cur].R);
    
        int lson = seg[cur].L, rson = seg[cur].R;
    
        seg[cur].mx = max(seg[lson].mx, seg[rson].mx);
        seg[cur].mi = min(seg[lson].mi, seg[rson].mi);
        seg[cur].sum = seg[lson].sum + seg[rson].sum;
    }
    
    void ask(int be, int en, int L, int R, long long int &sum, int &mx, int &mi, int cur) {
        if (L >= be && R <= en) {
            sum += seg[cur].sum;
            mx = max(seg[cur].mx, mx);
            mi = min(seg[cur].mi, mi);
            return;
        }
        int mid = (L + R) >> 1;
        if (be <= mid) {
            ask(be, en, L, mid, sum, mx, mi, seg[cur].L);
        }
        if (en >= mid + 1) {
            ask(be, en, mid + 1, R, sum, mx, mi, seg[cur].R);
        }
    }
    
    void work() {
        int n;
        scanf("%d", &n);
        build(1, n);
        int q;
        scanf("%d", &q);
        while (q--) {
            int op, one, two;
            scanf("%d%d%d", &op, &one, &two);
            if (op == 0) {
                update(one, two, 1, n, 1);
            } else {
                long long int sum = 0;
                int mx = -oo;
                int mi = oo;
                ask(one, two, 1, n, sum, mx, mi, 1);
                printf("%lld
    ", sum - mx - mi);
            }
        }
    }
    
    int main() {
        // freopen("data.txt", "r", stdin);
        work();
        return 0;
    }
    View Code

    http://codeforces.com/contest/984/problem/D

    画图,然后变成简单的区间DP

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 5e3 + 20;
    int dp[maxn][maxn];
    int f[maxn][maxn];
    int a[maxn];
    
    int dfs(int be, int en) {
        if (be > en) {
            assert(false);
        }
        if (be == en) return dp[be][en] = f[be][en] = a[be];
        if (f[be][en] != -1) return f[be][en];
        int left = dfs(be, en - 1);
        int right = dfs(be + 1, en);
    
        f[be][en] = left ^ right;
    
        dp[be][en] = max(dp[be + 1][en], max(dp[be][en - 1], left ^ right));
        return f[be][en];
    }
    
    void work() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                f[i][j] = dp[i][j] = -1;
            }
        }
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
        }
        int q;
        scanf("%d", &q);
        while (q--) {
            int L, R;
            scanf("%d%d", &L, &R);
            // cout << L << " " << R << endl;
            dfs(L, R);
            printf("%d
    ", dp[L][R]);
        }
    }
    
    int main() {
        // freopen("data.txt", "r", stdin);
        work();
        return 0;
    }
    View Code

    韩罗塔

    #include <cstdio>
    #include <cstdlib>
    #include <stack>
    
    void move(int val, char from, char broow, char to) {
        printf("%d from %c broow %c to %c
    ", val, from, broow, to);
    }
    int step;
    void dfs(int n, char a, char b, char c) {
        if (n == 0) return;
        step++;
        if (n == 1) {
            move(n, a, ' ', b);
            return;
        }
        dfs(n - 1, a, c, b);
        move(n, a, ' ', b);
        dfs(n - 1, c, b, a);
    }
    
    void work() {
        int n = 5;
        dfs(n, 'A', 'B', 'C');
        printf("%d
    ", step);
    }
    
    int main() {
        work();
        return 0;
    }
    View Code

    光明小学的小朋友们要举行一年一度的接力跑大赛了,但是小朋友们却遇到了一个难题:设计接力跑大赛的线路,你能帮助他们完成这项工作么?
    光明小学可以抽象成一张有N个节点的图,每两点间都有一条道路相连。光明小学的每个班都有M个学生,所以你要为他们设计出一条恰好经过M条边的路径。
    光明小学的小朋友们希望全盘考虑所有的因素,所以你需要把任意两点间经过M条边的最短路径的距离输出出来以供参考。
    你需要设计这样一个函数:
    res[][] Solve( N, M, map[][]);
    注意:map必然是N * N的二维数组,且map[i][j] == map[j][i],map[i][i] == 0,-1e8 <= map[i][j] <= 1e8。(道路全部是无向边,无自环)2 <= N <= 100, 2 <= M <= 1e6。要求时间复杂度控制在O(N^3*log(M))。
    map数组表示了一张稠密图,其中任意两个不同节点i,j间都有一条边,边的长度为map[i][j]。N表示其中的节点数。
    你要返回的数组也必然是一个N * N的二维数组,表示从i出发走到j,经过M条边的最短路径
    你的路径中应考虑包含重复边的情况。

    /*
    * @Author: vimiliu
    * @Date:   2018-07-18 15:18:42
    * @Last Modified by:   vimiliu
    * @Last Modified time: 2018-07-18 20:22:43
    */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 200 + 2;
    
    struct Matrix {
        int a[maxn][maxn];
        int col, row;
        void init() {
            for (int i = 1; i <= row; ++i) {
                for (int j = 1; j <= col; ++j) {
                    a[i][j] = -1; // can not go
                }
            }
        }
    };
    
    void show(struct Matrix a) {
        for (int i = 1; i <= a.row; ++i) {
            for (int j = 1; j <= a.col; ++j) {
                cout << a.a[i][j] << " ";
            }
            cout << endl;
        }
        cout << "debug ------ " << endl;
    }
    
    struct Matrix MatrixMul(struct Matrix a, struct Matrix b) {
        struct Matrix res;
        res.row = a.row; //行等于第一个矩阵的行
        res.col = b.col; //列等于第二个矩阵的列
        for (int i = 1; i <= a.row; ++i) {
            for (int j = 1; j <= a.col; ++j) {
                int val = -1; // can not go
                for (int k = 1; k <= b.row; ++k) {
                    if (a.a[i][k] == -1 || b.a[k][j] == -1) continue;
                    if (val == -1) val = a.a[i][k] + b.a[k][j];
                    else val = min(val, a.a[i][k] + b.a[k][j]);
                }
                res.a[i][j] = val;
            } 
        }
        return res;
    }
    
    struct Matrix MatrixQuickPow(struct Matrix a, struct Matrix b, int n) {
        while (n > 0) {
            if (n & 1) {
                a = MatrixMul(a, b);
            }
            b = MatrixMul(b, b);
            n >>= 1;
        }
        return a;
    }
    
    int e[maxn][maxn];
    int n;
    void inputData() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                scanf("%d", &e[i][j]);
                if (e[i][j] == 0) e[i][j] = -1;
            }
        }
    }
    
    void work() {
    
        struct Matrix I;
        I.row = I.col = n;
        I.init();
        for (int i = 1; i <= n; ++i) {
            I.a[i][i] = 0;
        }
        struct Matrix b;
        b.row = b.col = n;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                b.a[i][j] = e[i][j];
            }
        }
        // input data
        ///////////////////////////
        int m = 2;
        struct Matrix ans = MatrixQuickPow(I, b, m);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                printf("%d ", ans.a[i][j]);
            }
            printf("
    ");
        }
    
    }
    
    int main() {
        freopen("data.txt", "r", stdin);
        inputData();
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    1602液晶显示实验
    LNMP安装(二)
    LNMP安装(一)
    vim插件安装
    资料下载
    建表的sql
    time
    计算机里的加减乘除
    branch
    存储过程
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/9009309.html
Copyright © 2011-2022 走看看