数据结构题目-二叉树的遍历

目录

问题 BK: 二叉树非递归前序遍历-附加代码模式

问题 BL: 二叉树非递归中序遍历-附加代码模式

题 BM: 二叉树非递归后序遍历-附加代码模式

问题 BN: 求二叉树中序遍历序根节点的下标

问题 BO: 根据前序+中序还原二叉树

问题 BP: 算法6-12:自底向上的赫夫曼编码

问题 BQ: 视频合并问题

问题 BR: 二叉树实现的简单物种识别系统-附加代码模式

问题 BS: 静态链表存储的二叉树查找根节点

问题 BT: 基础实验4-2.1:树的同构

问题 BU: 哈夫曼树--查找值最小的两个叶节点

问题 BV: 静态链表存储的二叉树的非递归遍历算法-附加代码模式


问题 BK: 二叉树非递归前序遍历-附加代码模式

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:840解决:638

返回比赛提交提交记录侧边提交

题目描述

用二叉树的带虚结点表示的前序遍历序可以唯一的确定一棵二叉树,请用非递归算法实现二叉树的前序遍历。
本题为附加代码模式,以下代码为自动附加在同学们提交的代码后面。在本题的提示中有代码框架(若使用在线vscode答题的同学请注意不要拷贝题目中的代码框架,自己手打,不然会被封号。),请同学们拷贝后,修改,再注释掉部分代码,最后提交。
 

// please comment the following code when you sumbit to OJ

int main(){

    // char *str = "abd###ceg##h##f#i##";

    char str[2000];

    while(cin >> str)

    {

        BiTree tree;

        InitBiTree(tree);

        // 根据带空节点的前序遍历字符串构造二叉树

        CreateBiTree(tree, str);

        // 前序遍历递归算法

        PreTraverse(tree);

        cout << endl;

        // 前序遍历非递归算法

        string result = PreTraverse_nonRec(tree);

        cout << result << endl;

        DestroyBiTree(tree);

    }

    return 0;

}

输入

每行是一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。

输出

对每行输入,分别用递归和非递归两种算法输出对应二叉树的前序遍历序(不含虚结点)

样例输入 复制

ab##c##
#
ab###

样例输出 复制

abc
abc


ab
ab

提示

Sample Input的第二行表示一棵空树;


代码的框架如下:

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <queue>

#include <stack>

using namespace std;

struct BiNode

{

    string data;

    BiNode *lchild, *rchild;

};

typedef BiNode *BiTree;

int InitBiTree(BiTree &T)

{

    T = NULL;

return 0;

}

// 非递归前序遍历,返回遍历结果字符串

string PreTraverse_nonRec(BiTree T)

{

    // please write your code here

    string result = "";

    

    return result;

}

// 用带虚结点的前序遍历串str(每个字符对应一个结点)构造二叉树T,并返回剩余字符串

char *CreateBiTree(BiTree &T, char *str)

{

    // 约定#表示空结点

    if (*str == '#')

    {

        T = NULL;

        return str + 1;

    }

    // 创建结点

    T = new BiNode;

    T->data = *str;

    // 继续输入并构造左子树和右子树

    char * strAfterLeft = CreateBiTree(T->lchild, str + 1);

    char * strAfterRight = CreateBiTree(T->rchild, strAfterLeft);

    // 返回剩余的字符串

    return strAfterRight;

}

int PreTraverse(BiTree T){

    if (T == NULL) return 0;

    cout << T->data;

    PreTraverse(T->lchild);

    PreTraverse(T->rchild);

    return 0;

}

int DestroyBiTree(BiTree &T){

    if (T == NULL) return 0;

    DestroyBiTree(T->lchild);

    DestroyBiTree(T->rchild);

    delete T;

    T = NULL;

    return 0;

}

// please comment the following code when you sumbit to OJ

int main(){

    // char *str = "abd###ceg##h##f#i##";

    char str[2000];

    while(cin >> str)

    {

        BiTree tree;

        InitBiTree(tree);

        // 根据带空节点的前序遍历字符串构造二叉树

        CreateBiTree(tree, str);

        // 前序遍历递归算法

        PreTraverse(tree);

        cout << endl;

        // 前序遍历非递归算法

        string result = PreTraverse_nonRec(tree);

        cout << result << endl;

        DestroyBiTree(tree);

    }

    return 0;

}

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
 
struct BiNode
{
    string data;
    BiNode *lchild,*rchild;
};
 
typedef BiNode *BiTree;
 
int InitBiTree(BiTree &t)
{
    t=NULL;
    return 0;
}
 
string PreTraverse_nonRec(BiTree t)
{
    string result = "";
    stack<BiTree>ls;
    if(t!=NULL)
    ls.push(t);
    while(!ls.empty())
    {
        BiTree l =NULL;
        if(ls.top()->lchild!=NULL)
        l=ls.top()->lchild;
        BiTree r = NULL;
        if(ls.top()->rchild!=NULL)
        r=ls.top()->rchild;
        result+=ls.top()->data;
        ls.pop();
        if(r)
        ls.push(r);
        if(l)
        ls.push(l);
    }
    return result;
}
 
char *CreateBiTree(BiTree &T,char *str)
{
    if(*str=='#')
    {
        T=NULL;
        return str+1;
    }
    T=new BiNode;
    T->data = *str;
 
    char *strAfterLeft = CreateBiTree(T->lchild,str+1);
    char *strAfterRight = CreateBiTree(T->rchild,strAfterLeft);
 
    return strAfterRight;
}
 
int PreTraverse(BiTree t)
{
    if(t==NULL)
    return 0;
    cout<<t->data;
    PreTraverse(t->lchild);
    PreTraverse(t->rchild);
    return 0;
}
 
int DestroyBiTree(BiTree &T)
{
    if(T==NULL)
    return 0;
    DestroyBiTree(T->lchild);
    DestroyBiTree(T->rchild);
    delete T;
    T = NULL;
    return 0;
}
 
 
 
// int main()
// {
//     char str[2000];
//     while(cin>>str)
//     {
//         BiTree tree;
//         InitBiTree(tree);
//         CreateBiTree(tree,str);
//         PreTraverse(tree);
//         cout<<endl;
//         string result=PreTraverse_nonRec(tree);
//         cout<<result<<endl;
//         DestroyBiTree(tree);
//     }
//     return 0;
// }

问题 BL: 二叉树非递归中序遍历-附加代码模式

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:881解决:605

返回比赛提交提交记录侧边提交

题目描述

用二叉树的带虚结点表示的前序遍历序可以唯一的确定一棵二叉树,请用非递归算法实现二叉树的中序遍历。
本题为附加代码模式,以下代码为自动附加在同学们提交的代码后面。在本题的提示中有代码框架(若使用在线vscode答题的同学请注意不要拷贝题目中的代码框架,自己手打,不然会被封号。),请同学们拷贝后,修改,再注释掉部分代码,最后提交。
 

// please comment the following code when you sumbit to OJ

int main(){

    // char *str = "abd###ceg##h##f#i##";

    char str[2000];

    while(cin >> str)

    {

        BiTree tree;

        InitBiTree(tree);

        // 根据带空节点的前序遍历字符串构造二叉树

        CreateBiTree(tree, str);

        // 中序遍历递归算法

        InTraverse(tree);

        cout << endl;

        // 中序遍历非递归算法

        string result = InTraverse_nonRec(tree);

        cout << result << endl;

        DestroyBiTree(tree);

    }

    return 0;

}

输入

每行是一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。

输出

对每行输入,分别用递归和非递归两种算法输出对应二叉树的中序遍历序(不含虚结点)

样例输入 复制

ab##c##
#
ab###

样例输出 复制

bac
bac


ba
ba

提示

Sample Input的第二行表示一棵空树;


代码的框架如下(代码中有几个小错误,需要修复~):

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <queue>

#include <stack>

using namespace std;

struct BiNode

{

    string data;

    BiNode *lchild, *rchild;

};

typedef BiNode *BiTree;

int InitBiTree(BiTree &T)

{

    T = NULL;

return 0;

}

// 非递归中序遍历,返回遍历结果字符串

string InTraverse_nonRec(BiTree T)

{

    // please write your code here

    string result = "";

    return result;

}

// 用带虚结点的前序遍历串str(每个字符对应一个结点)构造二叉树T,并返回剩余字符串

char *CreateBiTree(BiTree &T, char *str)

{

    // 约定#表示空结点

    if (*str == '#')

    {

        T = NULL;

        return str + 1;

    }

    // 创建结点

    T = new BiNode;

    T->data = *str;

    // 继续输入并构造左子树和右子树

    char * strAfterLeft = CreateBiTree(T->lchild, str + 1);

    char * strAfterRight = CreateBiTree(T->rchild, strAfterLeft);

    // 返回剩余的字符串

    return strAfterRight;

}

int InTraverse(BiTree T){

    if (T == NULL) return 0;

    cout << T->data;

    PreTraverse(T->lchild);

    PreTraverse(T->rchild);

    return 0;

}

int DestroyBiTree(BiTree &T){

    if (T == NULL) return 0;

    DestroyBiTree(T->lchild);

    DestroyBiTree(T->rchild);

    delete T;

    T = NULL;

    return 0;

}

// please comment the following code when you sumbit to OJ

int main(){

    // char *str = "abd###ceg##h##f#i##";

    char str[2000];

    while(cin >> str)

    {

        BiTree tree;

        InitBiTree(tree);

        // 根据带空节点的前序遍历字符串构造二叉树

        CreateBiTree(tree, str);

        // 中序遍历递归算法

        InTraverse(tree);

        cout << endl;

        // 中序遍历非递归算法

        string result = InTraverse_nonRec(tree);

        cout << result << endl;

        DestroyBiTree(tree);

    }

    return 0;

}

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
 
struct BiNode
{
    string data;
    BiNode *lchild,*rchild;
};
 
typedef BiNode *BiTree;
 
int InitBiTree(BiTree &t)
{
    t=NULL;
    return 0;
}
 
string InTraverse_nonRec(BiTree t)
{
    string result = "";
    stack<BiTree>ls;
    while(t!=NULL || !ls.empty())
    {
       while(t!=NULL)
       {
           ls.push(t);
           t=t->lchild;
       }
       if(!ls.empty())
       {
           BiTree temp = ls.top();
           result+=temp->data;
           ls.pop();
           t=temp->rchild;
       }
    }
    return result;
}
 
char *CreateBiTree(BiTree &T,char *str)
{
    if(*str=='#')
    {
        T=NULL;
        return str+1;
    }
    T=new BiNode;
    T->data = *str;
 
    char *strAfterLeft = CreateBiTree(T->lchild,str+1);
    char *strAfterRight = CreateBiTree(T->rchild,strAfterLeft);
 
    return strAfterRight;
}
 
int InTraverse(BiTree t)
{
    if(t==NULL)
    return 0;
    InTraverse(t->lchild);
    cout<<t->data;
    InTraverse(t->rchild);
    return 0;
}
 
int DestroyBiTree(BiTree &T)
{
    if(T==NULL)
    return 0;
    DestroyBiTree(T->lchild);
    DestroyBiTree(T->rchild);
    delete T;
    T = NULL;
    return 0;
}
 
 
 
// int main()
// {
//     char str[2000];
//     while(cin>>str)
//     {
//         BiTree tree;
//         InitBiTree(tree);
//         CreateBiTree(tree,str);
//         InTraverse(tree);
//         cout<<endl;
//         string result=InTraverse_nonRec(tree);
//         cout<<result<<endl;
//         DestroyBiTree(tree);
//     }
//     return 0;
// }

题 BM: 二叉树非递归后序遍历-附加代码模式

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:645解决:619

返回比赛提交提交记录侧边提交

题目描述

用二叉树的带虚结点表示的前序遍历序可以唯一的确定一棵二叉树,请用非递归算法实现二叉树的后序遍历。
本题为附加代码模式,以下代码为自动附加在同学们提交的代码后面。在本题的提示中有代码框架(若使用在线vscode答题的同学请注意不要拷贝题目中的代码框架,自己手打,不然会被封号。),请同学们拷贝后,修改,再注释掉部分代码,最后提交。
 

// please comment the following code when you sumbit to OJ

int main(){

    // char *str = "abd###ceg##h##f#i##";

    char str[2000];

    while(cin >> str)

    {

        BiTree tree;

        InitBiTree(tree);

        // 根据带空节点的前序遍历字符串构造二叉树

        CreateBiTree(tree, str);

        // 后序遍历递归算法

        SucTraverse(tree);

        cout << endl;

        // 后序遍历非递归算法

        string result = SucTraverse_nonRec(tree);

        cout << result << endl;

        DestroyBiTree(tree);

    }

    return 0;

}



 

输入

每行是一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。

输出

对每行输入,分别用递归和非递归两种算法输出对应二叉树的后序遍历序(不含虚结点)

样例输入 复制

ab##c##
#
ab###

样例输出 复制

bca
bca


ba
ba

提示

Sample Input的第二行表示一棵空树;


代码的框架如下:

 

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <queue>

#include <stack>

using namespace std;

struct BiNode

{

    string data;

    BiNode *lchild, *rchild;

};

typedef BiNode *BiTree;

int InitBiTree(BiTree &T)

{

    T = NULL;

    return 0;

}

// 非递归后序遍历,返回遍历结果字符串

string SucTraverse_nonRec(BiTree T)

{

    // please write your code here

    string result = "";

    return result;

}

// 用带虚结点的前序遍历串str(每个字符对应一个结点)构造二叉树T,并返回剩余字符串

char *CreateBiTree(BiTree &T, char *str)

{

    // 约定#表示空结点

    if (*str == '#')

    {

        T = NULL;

        return str + 1;

    }

    // 创建结点

    T = new BiNode;

    T->data = *str;

    // 继续输入并构造左子树和右子树

    char * strAfterLeft = CreateBiTree(T->lchild, str + 1);

    char * strAfterRight = CreateBiTree(T->rchild, strAfterLeft);

    // 返回剩余的字符串

    return strAfterRight;

}

int SucTraverse(BiTree T){

    if (T == NULL) return 0;

    SucTraverse(T->lchild);

    SucTraverse(T->rchild);

    cout << T->data;

    return 0;

}

int DestroyBiTree(BiTree &T){

    if (T == NULL) return 0;

    DestroyBiTree(T->lchild);

    DestroyBiTree(T->rchild);

    delete T;

    T = NULL;

    return 0;

}

// please comment the following code when you sumbit to OJ

int main(){

    // char *str = "abd###ceg##h##f#i##";

    char str[2000];

    while(cin >> str)

    {

        BiTree tree;

        InitBiTree(tree);

        // 根据带空节点的前序遍历字符串构造二叉树

        CreateBiTree(tree, str);

        // 后序遍历递归算法

        SucTraverse(tree);

        cout << endl;

        // 后序遍历非递归算法

        string result = SucTraverse_nonRec(tree);

        cout << result << endl;

        DestroyBiTree(tree);

    }

    return 0;

}

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
 
struct BiNode
{
    string data;
    BiNode *lchild,*rchild;
};
 
typedef BiNode *BiTree;
 
int InitBiTree(BiTree &t)
{
    t=NULL;
    return 0;
}
 
string SucTraverse_nonRec(BiTree t)
{
    string result = "";
    stack<BiTree>ls;
    BiTree temp=NULL;
    while(t!=NULL || !ls.empty())
    {
        if(t!=NULL)
        {
            ls.push(t);
            t=t->lchild;
        }
        else
        {
            t = ls.top();
            if(t->rchild!=NULL&&t->rchild!=temp)
            {
               t=t->rchild;
            }
            else
            {
                    ls.pop();
                    result+=t->data;
                    temp=t;
                    t=NULL;
            }
        }
    }
    return result;
}
 
char *CreateBiTree(BiTree &T,char *str)
{
    if(*str=='#')
    {
        T=NULL;
        return str+1;
    }
    T=new BiNode;
    T->data = *str;
 
    char *strAfterLeft = CreateBiTree(T->lchild,str+1);
    char *strAfterRight = CreateBiTree(T->rchild,strAfterLeft);
 
    return strAfterRight;
}
 
int SucTraverse(BiTree t)
{
    if(t==NULL)
    return 0;
    SucTraverse(t->lchild);
    SucTraverse(t->rchild);
    cout<<t->data;
    return 0;
}
 
int DestroyBiTree(BiTree &T)
{
    if(T==NULL)
    return 0;
    DestroyBiTree(T->lchild);
    DestroyBiTree(T->rchild);
    delete T;
    T = NULL;
    return 0;
}
 
 
 
// int main()
// {
//     char str[2000];
//     while(cin>>str)
//     {
//         BiTree tree;
//         InitBiTree(tree);
//         CreateBiTree(tree,str);
//         SucTraverse(tree);
//         cout<<endl;
//         string result=SucTraverse_nonRec(tree);
//         cout<<result<<endl;
//         DestroyBiTree(tree);
//     }
//     return 0;
// }

问题 BN: 求二叉树中序遍历序根节点的下标

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:2866解决:1715

返回比赛提交提交记录侧边提交

题目描述

用一棵二叉树的前序遍历序和中序遍历序可以唯一确定一棵二叉树,这个算法的核心操作是根据前序遍历序,查找中序遍历序中根节点的位置,以确定左子树序列,根节点,和右子树序列。然后递归找到每个子树的根节点就可以完成二叉树的构造。

输入

每行输入为一棵非空二叉树的前序遍历序串和中序遍历序串(两串长度均不超过2000),前序遍历序和中序遍历序中间用一个空格隔开。 每个结点为一个字符(字母或数字),且不存在相同结点。

输出

对每行输入,输出根节点在中序遍历序列中的下标

样例输入 复制

abc bac
ab ba

样例输出 复制

1
1
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s1,s2;
    while(cin>>s1>>s2)
    {
        char temp=s1[0];
        for(int i=0;i<s2.length();i++)
        {
            if(temp==s2[i])
            {
                cout<<i<<endl;
                break;
            }
        }
    }
}

问题 BO: 根据前序+中序还原二叉树

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:1225解决:977

返回比赛提交提交记录侧边提交

题目描述

用一棵二叉树的前序遍历序和中序遍历序可以唯一确定一棵二叉树。

输入

每行输入为一棵非空二叉树的前序遍历序串和中序遍历序串(两串长度均不超过2000),前序遍历序和中序遍历序中间用一个空格隔开。 每个结点为一个字符(字母或数字),且不存在相同结点。

输出

对每行输入,输出对应二叉树的后序遍历序后换行

样例输入 复制

abc bac
ab ba

样例输出 复制

bca
ba
#include<bits/stdc++.h>
using namespace std;
 
struct BiNode
{
    string data;
    BiNode *lchild,*rchild;
};
 
typedef BiNode *BiTree;
 
int InitBiTree(BiTree &t)
{
    t=NULL;
    return 0;
}
 
BiNode *create(string s1,string s2,int len)
{
    BiNode *node=NULL;
    node = (BiNode*)malloc(sizeof(BiNode));
    string pls="",prs="";
    string ils="",irs="";
    if(len==0)
    return NULL;
    node->data = s1[0];
    int index=0;
    for(int i=0;i<len;i++)
    {
        if(s2[i]==s1[0])
        {
            index=i;
            break;
        }
    }
    for(int i=0;i<index;i++)
    ils+=s2[i];
    for(int i=index+1;i<len;i++)
    irs+=s2[i];
    for(int i=1;i<=index;i++)
    pls+=s1[i];
    for(int i=index+1;i<len;i++)
    prs+=s1[i];
    node->lchild=create(pls,ils,index);
    node->rchild=create(prs,irs,len-index-1);
    return node;
}
 
int h(BiTree tree)
{
    if(tree==NULL)
    return 0;
    h(tree->lchild);
    h(tree->rchild);
    cout<<tree->data;
    return 0;
}
 
 
int main()
{
    string s1,s2;
    while(cin>>s1>>s2)
    {
        int n=s1.length();
        BiTree tree;
        InitBiTree(tree);
        tree = create(s1,s2,n);
        h(tree);
        cout<<endl;
    }
}

问题 BP: 算法6-12:自底向上的赫夫曼编码

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:2011014323

提交:1995解决:1359

返回比赛提交提交记录侧边提交

题目描述

在通讯领域,经常需要将需要传送的文字转换成由二进制字符组成的字符串。在实际应用中,由于总是希望被传送的内容总长尽可能的短,如果对每个字符设计长度不等的编码,且让内容中出现次数较多的字符采用尽可能短的编码,则整个内容的总长便可以减少。另外,需要保证任何一个字符的编码都不是另一个字符的编码前缀,这种编码成为前缀编码。

而赫夫曼编码就是一种二进制前缀编码,其从叶子到根(自底向上)逆向求出每个字符的算法可以表示如下:

在本题中,读入n个字符所对应的权值,生成赫夫曼编码,并依次输出计算出的每一个赫夫曼编码。

输入

输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。 第二行中有n个用空格隔开的正整数,分别表示n个字符的权值。

输出

共n行,每行一个字符串,表示对应字符的赫夫曼编码。

样例输入 复制

8
5 29 7 8 14 23 3 11

样例输出 复制

0110
10
1110
1111
110
00
0111
010

提示

满足条件的哈夫曼树不止一种。为了确保答案唯一,题目的测试数据约定,合并两个节点时,先出现的节点(也就是数组中下标小的节点)为左子;

#include<bits/stdc++.h>
using namespace std;
typedef struct
{
    int parent;
    int weight;
    int lchild;
    int rchild;
}HuffNode;
 
HuffNode h[205];
 
typedef struct
{
    char code[15];
}HuffTree;
 
HuffTree hcd[105];
 
int createtree(HuffNode hn[],int n)
{
    for(int i=n;i<2*n-1;i++)
    h[i].weight=0;
    for(int i=0;i<2*n-1;i++)
    h[i].parent=h[i].lchild=h[i].rchild=-1;
    for(int i=n;i<2*n-1;i++)
    {
        int min1=INT_MAX,min2=INT_MAX;
        int index1,index2;
        for(int j=0;j<i;j++)
        {
            if(h[j].weight<min1&&h[j].parent==-1)
            {
                min1=h[j].weight;
                index1=j;
            }
        }
        h[index1].parent=i;
        for(int j=0;j<i;j++)
        {
            if(h[j].weight<min2&&h[j].parent==-1)
            {
                min2=h[j].weight;
                index2=j;
            }
        }
        h[index2].parent=i;
        if(index1>index2)
        {
            swap(min1,min2);
            swap(index1,index2);
        }
        h[i].weight=min1+min2;
        h[i].lchild=index1;
        h[i].rchild=index2;
    }
    return 0;
}
 
int createcode(HuffNode h[],HuffTree hcd[],int n)
{
    int head=0;
    char s[15];
    for(int i=0;i<n;i++)
    {
        int par=h[i].parent;
        int j=i;
        while(par!=-1)
        {
            if(h[par].lchild==j)
            s[head]='0';
            else
            s[head]='1';
            head++;
            j=par;
            par=h[par].parent;
        }
        int k=0;
        while(head>0)
        {
            head--;
            hcd[i].code[k]=s[head];
            k++;
        }
        cout<<hcd[i].code<<endl;
        head=0;
    }
    return 0;
}
 
int main()
{
    int n;
    cin>>n;
    int a[105];
    for(int i=0;i<n;i++)
    cin>>h[i].weight;
    createtree(h,n);
    createcode(h,hcd,n);
}

问题 BQ: 视频合并问题

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:1781解决:1336

返回比赛提交提交记录侧边提交

题目描述

有多个视频需要合并为一个视频,假设一次只能将两个视频进行合并,合并需要的时间为该两个视频的时间之和。请计算将多个视频合并为一个视频需要的最小时间为多少?

输入

输入的第一行包含一个正整数n,表示共有n个视频需要合并。其中n不超过100。 第二行中有n个用空格隔开的正整数,分别表示n个视频的时间。

输出

输出包括一个正整数,即合并需要的最小时间。

样例输入 复制

8
5 29 7 8 14 23 3 11

样例输出 复制

271
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
 
int main()
{
    int n;
    cin>>n;
    int a[105];
    for(int i=0;i<n;i++)
    cin>>a[i];
    sort(a,a+n);
    int m=n-1;
    ll ans=0;
    for(int i=0;i<m;i++)
    {
        a[0]+=a[1];
        ans+=a[0];
        for(int j=1;j<n;j++)
        a[j]=a[j+1];
        n--;
        sort(a,a+n);
    }
    cout<<ans<<endl;
}

问题 BR: 二叉树实现的简单物种识别系统-附加代码模式

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:869解决:562

返回比赛提交提交记录侧边提交

题目描述

用二叉树可以实现一个简单的物种识别系统,举例如下:

请编写代码根据上面的系统完成物种识别过程。注意问题对应的左节点表示回答的是no,右节点表示回答的yes





 

输入

输入包括两行,分别是每个问题的回答,y或者Y表示yes,n或者N表示no

输出

输出对应的物种识别结果

样例输入 复制

y
y

样例输出 复制

the answer is:eagle

提示

本题为附加代码模式,代码框架如下:

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <queue>

#include <stack>

using namespace std;

struct BiNode

{

    string data;

    BiNode *lchild, *rchild;

};

typedef BiNode *BiTree;

int InitBiTree(BiTree &T)

{

    T = NULL;

    return 0;

}

BiNode *StartRecognize(BiTree T)

{

    

}

BiNode* getNode(string data){

    BiNode* node = new BiNode();

    node->data = data;

    node->lchild = node->rchild = nullptr;
    return node;

}


 

// please comment the following code when you sumbit to OJ

// 构造一个三层的物种识别系统,第一层是一个问题,第二层是两个问题,第三层是四种动物

BiTree setRecognizeSystem(){

    BiTree T = getNode("Can it fly?");

    BiNode* n1 = getNode("Is it dangerous");

    BiNode* n2 = getNode("Does it eat meat?");

    BiNode* n3 = getNode("rabbit");

    BiNode* n4 = getNode("tiger");

    BiNode* n5 = getNode("swallow");

    BiNode* n6 = getNode("eagle");

    

    T->lchild = n1;  T->rchild = n2;

    n1->lchild = n3;  n1->rchild = n4;

    n2->lchild = n5;  n2->rchild = n6;

    return T;

}

int main(){

    // freopen("/config/workspace/answer/BiTreeFiles/test.in","r",stdin);

    BiTree T = setRecognizeSystem();

    BiNode *p = StartRecognize(T);

    if(p != nullptr)    cout << "the answer is:" << p->data << endl;

    return 0;

}

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
 
struct BiNode
{
    string data;
    BiNode *lchild,*rchild;
};
 
typedef BiNode *BiTree;
 
int InitBiTree(BiTree & t)
{
    t=NULL;
    return 0;
}
 
BiNode *StartRecognize(BiTree t)
{
    BiNode *ans=NULL;
    BiTree temp = t;
    char q1,q2;
    cin>>q1>>q2;
    if(q1=='y'||q1=='Y')
    {
        temp = t->rchild;
        if(q2=='y'||q2=='Y')
        {
            temp = temp->rchild;
            ans=temp;
        }
        else
        {
            temp = temp->lchild;
            ans=temp;
        }
    }
    else
    {
        temp = t->lchild;
        if(q2=='y'||q2=='Y')
        {
            temp = temp->rchild;
            ans=temp;
        }
        else
        {
            temp = temp->lchild;
            ans=temp;
        }
    }
    return ans;
 
}
 
BiNode* getNode(string data)
{
    BiNode* node=new BiNode();
    node->data = data;
    node->lchild=node->rchild=nullptr;
    return node;
}
 
// BiTree setRecognizeSystem()
// {
//     BiTree t = getNode("Can it fly?");
//     BiNode* n1 = getNode("Is it dangerous?");
//     BiNode* n2=getNode("Does it eat meat?");
//     BiNode* n3=getNode("rabbit");
//     BiNode* n4=getNode("tiger");
//     BiNode* n5=getNode("swallow");
//     BiNode* n6=getNode("eagle");
 
//     t->lchild = n1;
//     t->rchild = n2;
//     n1->lchild = n3;
//     n1->rchild = n4;
//     n2->lchild = n5;
//     n2->rchild = n6;
 
//     return t;
// }
 
// int main()
// {
//     BiTree t = setRecognizeSystem();
//     BiNode *p = StartRecognize(t);
//     if(p!=nullptr)
//     cout<<"the answer is: "<<p->data<<endl;
//     return 0;
// }

问题 BS: 静态链表存储的二叉树查找根节点

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:856解决:527

返回比赛提交提交记录侧边提交

题目描述

用数组模拟实现链表的功能,即静态链表,也可以用来存储二叉树。
请编写程序,输出静态链表存储的二叉树的根节点

输入

输入给出2棵二叉树树的信息。
对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);
随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。
如果孩子结点为空,则在相应位置上给出“-”。
给出的数据间用一个空格分隔。
注意:题目保证每个结点中存储的字母是不同的。

输出

针对每颗二叉树,输出根节点。
如果二叉树为空,则输出空行。

样例输入 复制

8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -

样例输出 复制

A
A
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
 
struct info
{
    char data;
    char lchild,rchild;
}b[15];
 
int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0)
        {
            int temp;
            cin>>temp;
            cout<<endl;
            continue;
        }
        int tempindex;
        int a[15];
        for(int i=0;i<15;i++)
        a[i]=0;
        for(int i=0;i<n;i++)
        {
            cin>>b[i].data>>b[i].lchild>>b[i].rchild;
            if(b[i].lchild>=48&&b[i].lchild<=57)
            {
                a[int(b[i].lchild)-48]++;
            }
            if(b[i].rchild>=48&&b[i].rchild<=57)
            {
                a[int(b[i].rchild)-48]++;
            }
        }
        for(int i=0;i<n;i++)
        if(a[i]==0)
        {
            tempindex=i;
            break;
        }
        cout<<b[tempindex].data<<endl;
    }
}

问题 BT: 基础实验4-2.1:树的同构

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:admin

提交:522解决:457

返回比赛提交提交记录侧边提交

题目描述

给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。






现给定两棵树,请你判断它们是否是同构的。
 

输入

输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。

输出

如果两棵树是同构的,输出“Yes”,否则输出“No”。

样例输入 复制

8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -

样例输出 复制

Yes

提示

可以用递归算法求解,判定规则如下:
(1)如果两棵树都为空,同构;
(2)一棵树为空,另一棵树不为空,不同构;
(3)两棵树都不为空,但根节点数据不同,不同构;
(4)两棵树的左子树都为空,则判断右子树是否同构;
(5)两棵树的左子树都不为空,且左子树的根节点值相等,判断两棵树的左子树是否同构,以及两棵树的右子树是否同构;
(6)两棵树的左右子树有一个为空,或者皆不为空但根节点不相等,需要判断一棵树的左/右子树和另一棵树的右/左子树是否同构;

#include<bits/stdc++.h>
using namespace std;
 
struct BiNode
{
    char data;
    int lchild;
    int rchild;
}t1[15],t2[15];
 
int creat(struct BiNode t[])
{
    int n;
    int root=0;
    char left,right;
    cin>>n;
    if(!n)
    return -1;
    for(int i=0;i<n;i++)
    {
        cin>>t[i].data>>left>>right;
        if(left=='-')
        t[i].lchild=-1;
        else
        {
            t[i].lchild=left-'0';
            root-=t[i].lchild;
        }
        if(right=='-')
        t[i].rchild=-1;
        else
        {
            t[i].rchild=right-'0';
            root-=t[i].rchild;
        }
        root += i;
    }
    return root;
}
 
bool judge(int r1,int r2)
{
    if(r1==-1&&r2==-1)
    return true;
    if(r1==-1&&r2!=-1||r1!=-1&&r2==-1)
    return false;
    if(t1[r1].data!=t2[r2].data)
    return false;
    if((t1[r1].lchild!=-1&&t2[r2].lchild!=-1)&&t1[t1[r1].lchild].data==t2[t2[r2].lchild].data)
    return judge(t1[r1].lchild,t2[r2].lchild)&&judge(t1[r1].rchild,t2[r2].rchild);
    else
    {
        return judge(t1[r1].rchild,t2[r2].lchild)&&judge(t1[r1].lchild,t2[r2].rchild);
    }
}
int main()
{
    int r1=creat(t1);
    int r2=creat(t2);
    if(judge(r1,r2))
    cout<<"Yes"<<endl;
    else
    {
        cout<<"No"<<endl;
    }
    return 0;
}

问题 BU: 哈夫曼树--查找值最小的两个叶节点

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:460解决:562

返回比赛提交提交记录侧边提交

题目描述

哈夫曼树的构造过程,最重要的是找到值最小的两个叶节点。

输入

输入第一行为整数n(n大于2且小于100),表示哈夫曼树的叶节点个数
接下来一行为n个整数,表示哈夫曼树的每个叶节点的值

输出

输出值最小的两个叶节点的下标。如果存在值相同的叶节点,优先输出下标小的节点。

样例输入 复制

8
5 29 7 8 14 23 3 11

样例输出 复制

6 0
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
 
struct data{
    int num;
    int index;
}a[105];
 
bool mysort(struct data b,struct data c)
{
    return b.num<c.num;
}
 
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
       cin>>a[i].num;
       a[i].index=i;
    }
    sort(a,a+n,mysort);
    cout<<a[0].index<<" "<<a[1].index;
}

问题 BV: 静态链表存储的二叉树的非递归遍历算法-附加代码模式

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:532解决:395

返回比赛提交提交记录侧边提交

题目描述

用数组模拟实现链表的功能,即静态链表,也可以用来存储二叉树。
请编写程序,用非递归遍历算法输出静态链表存储前中后三种遍历结果。
本题为附加代码模式,以下代码为自动附加在同学们提交的代码后面。在本题的提示中有代码框架(若使用在线vscode答题的同学请注意不要拷贝题目中的代码框架,自己手打,不然会被封号。),请同学们拷贝后,修改,再注释掉部分代码,最后提交。
 

// please comment the following code when you sumbit to OJ

void InputBiTree(BiTree & T){

    cin >> T.nodeNumber;

    for(int i=0;i<T.nodeNumber;i++){

        cin >> T.data[i].data >> T.data[i].lchild >> T.data[i].rchild;

    }

}

int main(){

    // freopen("/config/workspace/answer/test.in","r",stdin);

    BiTree T;

    InputBiTree(T);

    FindRootIndex(T);

    string str = getPreTraverseStr(T);

    cout << str << endl;

    str = getInTraverseStr(T);

    cout << str << endl;

    str = getSucTraverseStr(T);

    cout << str << endl;

    InputBiTree(T);

    FindRootIndex(T);

    str = getPreTraverseStr(T);

    cout << str << endl;

    str = getInTraverseStr(T);

    cout << str << endl;

    str = getSucTraverseStr(T);

    cout << str << endl;

    return 0;

}


 

输入

输入给出2棵二叉树树的信息。
对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);
随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。
如果孩子结点为空,则在相应位置上给出“-”。
给出的数据间用一个空格分隔。
注意:题目保证每个结点中存储的字母是不同的。

输出

针对每颗二叉树,输出3行,分别是前中后三种序列的遍历结果。
如果二叉树为空,则输出3个空行。

样例输入 复制

8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -

样例输出 复制

ABDEFCGH
DBFEAHGC
DFEBHGCA
ACGHBEFD
GHCAFEBD
HGCFEDBA

提示

代码框架如下:

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <queue>

#include <stack>

using namespace std;

struct BiNode

{

    string data;

    char lchild;

    char rchild;

};

struct BiTree

{

    int nodeNumber; // 节点总数

    BiNode data[10];// 节点数组

    int rootIndex;  // 根节点下标

};

// 遍历所有节点,确定根节点下标

void FindRootIndex(BiTree & T){

    

}

// 获得前序遍历结果字符串

string getPreTraverseStr(const BiTree & T){

    

}

// 获得中序遍历结果字符串

string getInTraverseStr(const BiTree & T){

    

}

// 获得后序遍历结果字符串

string getSucTraverseStr(const BiTree & T){

    

}


 

// please comment the following code when you sumbit to OJ

void InputBiTree(BiTree & T){

    cin >> T.nodeNumber;

    for(int i=0;i<T.nodeNumber;i++){

        cin >> T.data[i].data >> T.data[i].lchild >> T.data[i].rchild;

    }

}

int main(){

    freopen("/config/workspace/answer/test.in","r",stdin);

    BiTree T;

    InputBiTree(T);

    FindRootIndex(T);

    string str = getPreTraverseStr(T);

    cout << str << endl;

    str = getInTraverseStr(T);

    cout << str << endl;

    str = getSucTraverseStr(T);

    cout << str << endl;

    InputBiTree(T);

    FindRootIndex(T);

    str = getPreTraverseStr(T);

    cout << str << endl;

    str = getInTraverseStr(T);

    cout << str << endl;

    str = getSucTraverseStr(T);

    cout << str << endl;

    return 0;

}

#include<bits/stdc++.h>
using namespace std;
 
struct BiNode
{
    string data;
    char lchild;
    char rchild;
    int flag=0;
};
 
struct BiTree
{
    int nodeNumber;
    BiNode data[10];
    int rootIndex;
};
 
void FindRootIndex(BiTree &T)
{
    int a[10];
    for(int i=0;i<T.nodeNumber;i++)
    {
        a[i]=0;
    }
    for(int i=0;i<T.nodeNumber;i++)
    {
        if(T.data[i].lchild!='-')
        a[T.data[i].lchild-'0']++;
        if(T.data[i].rchild!='-')
        a[T.data[i].rchild-'0']++;
    }
    for(int i=0;i<T.nodeNumber;i++)
    {
        if(a[i]==0)
        {
            T.rootIndex=i;
            break;
        }
    }
}
 
string getPreTraverseStr(const BiTree &T)
{
    if(T.nodeNumber==0)
    return "";
    string ans="";
    stack<BiNode>temp;
    temp.push(T.data[T.rootIndex]);
    while (!temp.empty())
    {
        BiNode t;
        t=temp.top();
        temp.pop();
        ans+=t.data;
        if(t.rchild!='-')
        temp.push(T.data[t.rchild-'0']);
        if(t.lchild!='-')
        temp.push(T.data[t.lchild-'0']);
    }
    return ans;
     
}
string getInTraverseStr(const BiTree &T)
{
    if(T.nodeNumber==0)
    return "";
    string ans="";
    stack<BiNode>temp;
    temp.push(T.data[T.rootIndex]);
    while (!temp.empty())
    {
        if(temp.top().flag==0)
        {
            temp.top().flag++;
            if(temp.top().lchild!='-')
            temp.push(T.data[temp.top().lchild-'0']);
        }
        else
        {
            BiNode t;
            t=temp.top();
            temp.pop();
            ans+=t.data;
            if(t.rchild!='-')
            temp.push(T.data[t.rchild-'0']);
        }
    }
    return ans;
}
 
string getSucTraverseStr(const BiTree &T)
{
    if(T.nodeNumber==0)
    return "";
    string ans="";
    stack<BiNode>temp;
    temp.push(T.data[T.rootIndex]);
    while (!temp.empty())
    {
        if(temp.top().flag==0)
        {
            temp.top().flag++;
            if(temp.top().lchild!='-')
            temp.push(T.data[temp.top().lchild-'0']);
        }
        else if(temp.top().flag==1)
        {
            temp.top().flag++;
            if(temp.top().rchild!='-')
            temp.push(T.data[temp.top().rchild-'0']);
        }
        else
        {
            ans+=temp.top().data;
            temp.pop();
        }
    }
    return ans;
}
 
// void InputBiTree(BiTree &T)
// {
//     cin>>T.nodeNumber;
//     for(int i=0;i<T.nodeNumber;i++)
//     cin>>T.data[i].data>>T.data[i].lchild>>T.data[i].rchild;
// }
 
// int main()
// {
//     BiTree T;
//     InputBiTree(T);
//     FindRootIndex(T);
//     string str = getPreTraverseStr(T);
//     cout<<str<<endl;
//     str=getInTraverseStr(T);
//     cout<<str<<endl;
//     str=getSucTraverseStr(T);
//     cout<<str<<endl;
 
//     InputBiTree(T);
//     FindRootIndex(T);
//     str = getPreTraverseStr(T);
//     cout<<str<<endl;
//     str=getInTraverseStr(T);
//     cout<<str<<endl;
//     str=getSucTraverseStr(T);
//     cout<<str<<endl;
 
//     return 0;
// }
 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嗯嗯你说的对

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值