zoukankan      html  css  js  c++  java
  • 第五讲 树(下)

    05-树7:堆中的路径
    Description:

    将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。

    Input:

    每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。

    Output:

    对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。

    SampleInput:

    5 3
    46 23 26 24 10
    5 4 3

    SampleOutput:

    24 23 10
    46 23 10
    26 10

    Codes:
    //#define LOCAL
    
    #include <cstdio>
    
    #define M 1010
    #define S -10010
    int i, cnt, A[M] = {S};
    
    void insert(int a) {
        for(i=++cnt; A[i/2]>a; i/=2) A[i] = A[i/2];
        A[i] = a;
    }
    
    int main()
    {
        #ifdef LOCAL
            freopen("E:\Temp\input.txt", "r", stdin);
            freopen("E:\Temp\output.txt", "w", stdout);
        #endif
    
        int a, n, m;
        scanf("%d%d", &n, &m);
    
        while(n--) { scanf("%d", &a); insert(a); }
        while(m--) {
            scanf("%d", &a);
            printf("%d", A[a]); a /= 2;
            while(a) { printf(" %d", A[a]); a /= 2; } 
            printf("
    "); 
        }
    
        return 0;
    }
    
    05-树8:File Transfer.
    Description:

    We have a network of computers and a list of bi-directional connections. Each of these connections allows a file transfer from one computer to another. Is it possible to send a file from any computer on the network to any other?

    Input:

    Each input file contains one test case. For each test case, the first line contains N(2, 10^4), the total number of computers in a network. Each computer in the network is then represented by a positive integer between 1 and N. Then in the following lines, the input is given in the format: I c1 c2 where I stands for inputting a connection between c1 and c2; or C c1 c2 where C stands for checking if it is possible to transfer files between c1 and c2; or S where S stands for stopping this case.

    Output:

    For each C case, print in one line the word "yes" or "no" if it is possible or impossible to transfer files between c1 and c2, respectively. At the end of each case, print in one line "The network is connected." if there is a path between any pair of computers; or "There are k components." where k is the number of connected components in this network.

    SampleInput1:

    5
    C 3 2
    I 3 2
    C 1 5
    I 4 5
    I 2 4
    C 3 5
    S

    SampleOutput1:

    no
    no
    yes
    There are 2 components.

    SampleInput2:

    5
    C 3 2
    I 3 2
    C 1 5
    I 4 5
    I 2 4
    C 3 5
    I 1 3
    C 1 5
    S

    SampleOutput2:

    no
    no
    yes
    yes
    The network is connected.

    Codes:
    //#define LOCAL
    
    #include <cstdio>
    #include <cstdlib>
    
    int findS(int *s, int v) {
        while(s[v] >= 0) v = s[v];
        return v;
    }
    
    void unionS(int *s, int c1, int c2) {
        int r1 = findS(s, c1), r2 = findS(s, c2);
        if(s[r1] < s[r2]) { s[r1] += s[r2]; s[r2] = r1; }
        else { s[r2] += s[r1]; s[r1] = r2; }
    }
    
    int main()
    {
        #ifdef LOCAL
            freopen("E:\Temp\input.txt", "r", stdin);
            freopen("E:\Temp\output.txt", "w", stdout);
        #endif
    
        int i, n, c1, c2, cnt = 0; char c;
        scanf("%d
    %c", &n, &c);
        
        int *s = (int*)malloc(sizeof(int)*(n+1));
        for(i=0; i<=n; ++i) s[i] = -1;
        while(c != 'S') {
            scanf("%d%d", &c1, &c2);
            if(c == 'I') unionS(s, c1, c2);
            else if(c == 'C') {
                if(findS(s, c1) == findS(s, c2)) printf("yes
    ");
                else printf("no
    ");
            }
            scanf("
    %c", &c);
        }
    
        for(i=1; i<=n; ++i) if(s[i] < 0) ++cnt;
        if(cnt == 1) printf("The network is connected.
    ");
        else printf("There are %d components.
    ", cnt);
        free(s);
    
        return 0;
    }
    
    05-树9:Huffman Codes.
    Description:

    In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string "aaaxuaxz", we can observe that the frequencies of the characters 'a', 'x', 'u' and 'z' are 4, 2, 1 and 1, respectively. We may either encode the symbols as {'a'=0, 'x'=10, 'u'=110, 'z'=111}, or in another way as {'a'=1, 'x'=01, 'u'=001, 'z'=000}, both compress the string into 14 bits. Another set of code can be given as {'a'=0, 'x'=11, 'u'=100, 'z'=101}, but {'a'=0, 'x'=01, 'u'=011, 'z'=001} is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001. The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not.

    Input:

    Each input file contains one test case. For each case, the first line gives an integer N (2, 63), then followed by a line that contains all the N distinct characters and their frequencies in the following format: c[1] f[1] c[2] f[2] ... c[N] f[N] where c[i] is a character chosen from {'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}, and f[i] is the frequency of c[i] and is an integer no more than 1000. The next line gives a positive integer M (≤1000), then followed by M student submissions. Each student submission consists of N lines, each in the format: c[i] code[i] where c[i] is the i-th character and code[i] is an non-empty string of no more than 63 '0's and '1's.

    Output:

    For each test case, print in each line either "Yes" if the student's submission is correct, or "No" if not.

    Note: The optimal solution is not necessarily generated by Huffman algorithm. Any prefix code with code length being optimal is considered correct.

    SampleInput:

    7
    A 1 B 1 C 1 D 3 E 3 F 6 G 6
    4
    A 00000
    B 00001
    C 0001
    D 001
    E 01
    F 10
    G 11
    A 01010
    B 01011
    C 0100
    D 011
    E 10
    F 11
    G 00
    A 000
    B 001
    C 010
    D 011
    E 100
    F 101
    G 110
    A 00000
    B 00001
    C 0001
    D 001
    E 00
    F 10
    G 11

    SampleOutput:

    Yes
    Yes
    No
    No

    Codes:
    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    
    class HuffmanTree {
        struct Node {
            Node(int w = 0):weight(w), left(NULL), right(NULL), parent(NULL) {}
            int weight; Node *left, *right, *parent;
        };
    
        class MinHeap {
        public:
            MinHeap(int N) {
                cbtree = new Node*[N+1];
                cbtree[0] = new Node(-1);
                size = 0;
            };
            ~MinHeap() {
                delete cbtree[0];
                cbtree[0] = NULL;
                delete[] cbtree;
            }
            int Size() { return size; }
            void Insert(Node *item) {
                int i = ++size;
                for (; item->weight<cbtree[i/2]->weight; i/=2) cbtree[i] = cbtree[i/2];
                cbtree[i] = item; return;
            }
    
            Node* DeleteMin() {
                Node *min_node = cbtree[1];
                Node *last_node = cbtree[size];
                cbtree[size--] = NULL;
                int child, parant = 1;
                while (parant*2 <= size) {
                    child = 2*parant;
                    if (child!=size && cbtree[child+1]->weight<cbtree[child]->weight) ++child;
                    if (last_node->weight < cbtree[child]->weight) break;
                    else cbtree[parant] = cbtree[child];
                    parant = child;
                }
                cbtree[parant] = last_node;
                return min_node;
            }
    
        private:
            Node* *cbtree; int size; };
    public:
        HuffmanTree(int capacity):heap(capacity), root(NULL), leaves(0), wpl(0) {}
        ~HuffmanTree() {
            for (size_t i=0; i<nodes.size(); ++i) delete nodes[i];
        }
        void Insert(int item) {
            ++leaves;
            nodes.push_back(new Node(item));
            heap.Insert(nodes.back());
        }
        int GetWeight(int leave) { return nodes[leave]->weight; }
        int GetWPL() {
            if (!root) Build();
            if (!wpl) {
                for (int i=0; i<leaves; ++i) {
                    int depth = 0;
                    for (Node *leave=nodes[i]; leave->parent; leave=leave->parent) ++depth;
                    wpl += depth*nodes[i]->weight;
                }
            }
            return wpl;
        }
    private:
        Node *NextEmptyNode() {
            static int next = leaves;
            ++next; nodes[next] = new Node();
            return nodes[next];
        }
        void Build() {
            if (!root) {
                nodes.resize(2*leaves-1);
                for (int i=0; i<leaves-1; ++i) {
                    Node *merged = NextEmptyNode();
                    merged->left = heap.DeleteMin();
                    merged->right = heap.DeleteMin();
                    merged->weight = merged->right->weight+merged->right->weight;
                    merged->right->parent = merged->left->parent = merged;
                    heap.Insert(merged);
                }
                root = heap.DeleteMin();
            }
        }
    private:
        MinHeap heap; Node *root;
        int leaves, wpl;
        vector<Node*> nodes;
    };
    bool IsPrefixConflict(string codes[], int N) {
        for (size_t i=0; i<N; ++i) {
            for (size_t j=0; j!=i &&j<N; ++j) 
                if(!codes[j].find(codes[i])) return true;
        }
        return false;
    }
    
    int main() {
    
        int i, f, N, M; char c;
        cin >> N;
        HuffmanTree tree(N);
        for (i=0; i<N; ++i) { cin >> c >> f; tree.Insert(f); }
        cin >> M;
        
        for (size_t mstu=0 ; mstu<M; ++mstu) {
            string codes[64];
            for (size_t ncode=0; ncode<N; ++ncode) cin >> c >> codes[ncode];
            int wpl = 0;
            for (int kcode=0; kcode<N; ++kcode) wpl += (codes[kcode].length()*tree.GetWeight(kcode));
            if (!IsPrefixConflict(codes, N)&&wpl == tree.GetWPL()) cout << "Yes" << endl;
             else cout << "No" << endl;
        }
    
        return 0;
    }
  • 相关阅读:
    多功能回到顶部组件,速度可调控,带隐藏效果,返回过程中可回滚。
    可扩展进度条,商城常用!
    多功能万能模态框插件,项目实用,持续更新中...
    前端页面重构技巧总结TIP【持续更新...】
    微信小程序入门实例之记事本
    webpack1.x环境配置与打包基础【附带各种 "坑" 与解决方案!持续更新中...】
    CSS3利用背景渐变和background-size配合完成渐变与条纹效果[持续更新中...]
    CSS3利用一个div实现内圆角边框效果
    CSS3实现原腾讯视频透明边框,多重边框等(关于边框那些不为人知的事情)
    使用条件注释完成浏览器兼容
  • 原文地址:https://www.cnblogs.com/VincentValentine/p/6847288.html
Copyright © 2011-2022 走看看