zoukankan      html  css  js  c++  java
  • [Offer收割]编程练习赛42

    对局匹配

    直接贪心

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<string>
    #include<functional>
    #include<math.h>
    //#include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    void makedata() {
        freopen("input.txt", "w", stdout);
        cout << 200000 << endl;
    
        for(int i = 0; i < 200000; i++) cout << 1000000000 << ' ';
    
        fclose(stdout);
    }
    
    int a[110000];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        //makedata();
        std::ios::sync_with_stdio(0), cin.tie(0);
        int n, k;
        cin >> n >> k;
    
        for(int i = 0; i < n; i++) cin >> a[i];
    
        sort(a, a + n);
        int ptr = 0, ans = 0;
    
        while(ptr < n) {
            if(ptr + 2 < n && a[ptr + 2] - a[ptr] <= k) {
                ans++;
                ptr += 3;
            } else ptr++;
        }
    
        cout << ans << endl;
        return 0;
    }
    View Code

    稀疏矩阵乘积

    对应关系别搞乱就行了

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<string>
    #include<functional>
    #include<math.h>
    #include<set>
    #include <list>
    //#include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    
    int x[3000], y[3000], w[3000], b[3000][3000], c[3000][3000];
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        std::ios::sync_with_stdio(0), cin.tie(0);
        int n, p, q;
        int xx, yy, ww;
        cin >> n >> p >> q;
        for (int i = 0; i < p; i++)cin >> x[i] >> y[i] >> w[i];
        memset(b, 0, sizeof(b));
        for (int i = 0; i < q; i++) {
            cin >> xx >> yy >> ww;
            b[xx][yy] = ww;
        }
        memset(c, 0, sizeof(c));
        for (int i = 0; i < p; i++) {
            for (int j = 1; j <= n; j++) {
                c[x[i]][j] += w[i] * b[y[i]][j];
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (c[i][j] != 0) cout << i << ' ' << j << ' ' << c[i][j] << endl;
            }
        }
        return 0;
    }
    View Code

    树上的等差数列

    首先随便以某一个节点为根把树建起来。树上的一条路径可以看成是从某一个节点出发,在树结构上上升到某一个祖先节点,再下降到一个后代节点。记录father[x]为x节点的父节点,dep[x]为前两项为a[father[x]],a[x]的等差数列沿树结构向下最多能走的深度。枚举这个最高点r,把它的子节点按权值分类,枚举所有能构成等差数列的组合a1,a[r],a2,找到权值分别为a1和a2的子节点中dep值最大的点(且这两个点不为同一个点),那么产生了一个局部的最长等差数列l(a1)+1+l(a2),选出其中最大的输出。

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<vector>
    #include<algorithm>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<string>
    #include<functional>
    #include<math.h>
    #include<set>
    #include <list>
    //#include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    
    map<int, VI> mp[110000];
    int a[110000], father[110000], dep[110000];
    VI G[110000];
    
    void build(int x, int fa) {
        father[x] = fa;
        for (int i = 0; i < G[x].size(); i++) {
            int u = G[x][i];
            if (u == fa) continue;
            auto it = mp[x].find(a[u]);
            if (it == mp[x].end()) mp[x][a[u]] = VI();
            mp[x][a[u]].push_back(u);
            build(u, x);
        }
    }
    void calc(int x) {
        if (dep[x] != 0) return;
        int d = a[father[x]] - a[x];
        int aa = a[x] - d;
        auto it = mp[x].find(aa);
        if (it == mp[x].end()) {
            dep[x] = 1;
            return;
        }
        int tmp = 1;
        for (int i = 0; i < (*it).second.size(); i++) {
            int u = (*it).second[i];
            calc(u);
            if (dep[u] + 1 > tmp) tmp = dep[u] + 1;
        }
        dep[x] = tmp;
    }
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
    #endif
        std::ios::sync_with_stdio(0), cin.tie(0);
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i < n; i++) {
            int u, v;
            cin >> u >> v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        build(1, 0);
        memset(dep, 0, sizeof(dep));
        for (int i = 2; i <= n; i++) calc(i);
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            for (auto itl = mp[i].begin(); itl != mp[i].end(); itl++) {
                int lval = (*itl).first, ldep = 0, ldot = 0;
                for (int j = 0; j < (*itl).second.size(); j++) {
                    if (dep[(*itl).second[j]] > ldep) {
                        ldep = dep[(*itl).second[j]];
                        ldot = (*itl).second[j];
                    }
                }
                int rval = 2 * a[i] - lval, rdep = 0, rdot = 0;
                auto itr = mp[i].find(rval);
                if (itr == mp[i].end()) {
                    if (ldep + 1 > ans) ans = ldep + 1;
                    continue;
                }
                for (int j = 0; j < (*itr).second.size(); j++) {
                    if (dep[(*itr).second[j]] > rdep && (*itr).second[j] != ldot) {
                        rdep = dep[(*itr).second[j]];
                        rdot = (*itr).second[j];
                    }
                }
                if (ldep + 1 + rdep > ans)  ans = ldep + 1 + rdep;
            }
        }
        cout << ans << endl;
        return 0;
    }
    View Code

    翻转字符串

    可以用Splay树实现反转操作。首先根据整个字符串建树,对于每次操作(l,r),首先把l左边的字符旋转到根节点上,此时(l,r)位于根节点的右子树上;然后把r右边的字符旋转到根节点的右子树的树根,这样一来,就得到了只由(l,r)构成的一棵子树:根节点的右子树的左子树,对其添加一个lazy标记,最后对树进行一个前序遍历即可。

    #include<iostream>  
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    const int maxLength = 100002;
    class Node{
    public:
        Node *child[2];
        char value;
        int size;
        bool flip;
        Node(char c) :value(c), size(1), flip(false){
            child[0] = child[1] = NULL;
        }
        int getPosition()const{
            return child[0] ? child[0]->size + 1 : 1;
        }
        void maintain();
        void pushDown();
    };
    void Node::maintain(){
        size = 1;
        if (child[0]){
            size += child[0]->size;
        }
        if (child[1]){
            size += child[1]->size;
        }
    }
    void Node::pushDown(){
        if (flip){
            swap(child[0], child[1]);
            for (int i = 0; i < 2; i++){
                if (child[i]){
                    child[i]->flip ^= 1;
                }
            }
            flip = false;
        }
    }
    class SplayTree{
    public:
        Node *root;
        SplayTree(char *a, int n);
        void build(Node *&node, char *begin, char *end);
        void rotate(Node *&node, int direction);
        void splay(Node *&node, int position);
        void reverse(int begin, int end);
        void traverse(Node *u);
        void traverse();
    };
    SplayTree::SplayTree(char *a, int n){
        build(root, a, a + n - 1);
    }
    void SplayTree::build(Node *&node, char *begin, char *end){
        if (begin > end){
            return;
        }
        char *middle = begin + (end - begin >> 1);
        node = new Node(*middle);
        build(node->child[0], begin, middle - 1);
        build(node->child[1], middle + 1, end);
        node->maintain();
    }
    
    void SplayTree::rotate(Node *&node, int direction){
        Node *child = node->child[direction ^ 1];
        node->child[direction ^ 1] = child->child[direction];
        child->child[direction] = node;
        node->maintain();
        child->maintain();
        node = child;
    }
    void SplayTree::splay(Node *&node, int position){
        node->pushDown();
        if (node->getPosition() != position){
            int d = node->getPosition() < position;
            Node *node2 = node->child[d];
            position -= d ? node->getPosition() : 0;
            node2->pushDown();
            if (node2->getPosition() != position){
                int d2 = node2->getPosition() < position;
                position -= d2 ? node2->getPosition() : 0;
                splay(node2->child[d2], position);
                if (d == d2){
                    rotate(node, d ^ 1);
                }
                else{
                    rotate(node->child[d], d);
                }
            }
            rotate(node, d ^ 1);
        }
    }
    void SplayTree::reverse(int begin, int end){
        splay(root, begin);
        splay(root->child[1], end - begin + 2);
        root->child[1]->child[0]->flip ^= 1;
    }
    void SplayTree::traverse(Node *u){
        if (!u){
            return;
        }
        u->pushDown();
        traverse(u->child[0]);
        if (u->value){
            printf("%c", u->value);
        }
        traverse(u->child[1]);
        
    }
    void SplayTree::traverse(){
        traverse(root);
    }
    int main(){
        char s[maxLength] = "";
        while (~scanf("%s", s + 1)){
            int n = strlen(s + 1);
            SplayTree splay(s, n + 2);
            int k;
            scanf("%d", &k);
            for (int i = 0; i < k; i++){
                int begin, end;
                scanf("%d%d", &begin, &end);
                splay.reverse(begin + 1, end + 1);
            }
            splay.traverse();
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【渗透攻防】深入了解Windows
    浅析B/S架构数据库连接方式
    剖析泄露你银行卡密码的钓鱼网站:真假“10086”
    红黑树的删除和加入节点
    Unity里包裹Debug,且不影响Debug的重定向
    Java向上转型和向下转型(附具体样例)
    Javascript 方法apply和call的差别
    普通androidproject转换为C/C++project之后,再还原成androidproject的解决方式
    初识双网卡
    js面向对象编程: js类定义函数时prototype和this差别?
  • 原文地址:https://www.cnblogs.com/dramstadt/p/8168748.html
Copyright © 2011-2022 走看看