暑期集训2期6

对称二叉树(削弱版)

如果二叉树的左右子树的结构是对称的,即两棵子树皆为空,或者皆不空,则称该二叉树是对称的。编程判断给定的二叉树是否对称。
例:如下图中的二叉树T1是对称的,T2是不对称的。
二叉树用顺序结构给出,若读到#则为空,二叉树T1=ABCDE,T2=ABCD#E,如果二叉树是对称的,输出“Yes”,反之输出“No”。

可以根据题意发现他给你的肯定是完全二叉树(包括#),那么我们可以从第二个开始两个两个判断,要都有或者都#

#include<bits/stdc++.h>
using namespace std;
string s;
int main()
{
    
    
    cin>>s;
    if(s.size()%2==0)//肯定不能是二叉树了
    {
    
    
        cout<<"No";
        return 0;
    }
    for(int i=1;i<s.size();i+=2)
    if(s[i]=='#'&&s[i+1]!='#'||s[i]!='#'&&s[i+1]=='#')
    {
    
    
        cout<<"No";
        return  0;
    }
    cout<<"Yes";
    return 0;
}


树的遍历

题目大概意思就是给你中序遍and按层遍历然后输出先序
DBEAC
ABCDE
模拟一下

先是找到A
变成 DBE
C
然后找到 B
变成 D
E
这样找出了答案了

#include<bits/stdc++.h>
using namespace std;
int  len;
char s[15000],s1[15000];
inline void dfs(int l,int r)
{
    
    
    if(l>r)return;
     
    int mid;
    for(int i=1;i<=len;i++)
    {
    
    
        for(int j=l;j<=r;j++)
        {
    
    
            if(s1[i]==s[j])
            {
    
    
                mid=j;
                j=r+1;
                i=len+1;//强制退出循环
            }
        }
    }
    cout<<s[mid];根左右
    dfs(l,mid-1);//左边
    dfs(mid+1,r);//右边
}
int main()
{
    
    
    scanf("%s",&s);
    len=strlen(s);
    for(int i=len;i>0;i--)s[i]=s[i-1];//往前移1位
    scanf("%s",&s1);
    for(int i=len;i>0;i--)s1[i]=s1[i-1];
     
    dfs(1,len);
    return 0;
}


二叉树在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int  n,p,k;
int a[150000],vis[150000];
inline void qx(int x)
{
    
    //根左右
    cout<<a[x]<<' ';
    if(x*2<=n)qx(x*2);
    if(x*2+1<=n)qx(x*2+1);
}
inline void zx(int x)
{
    
    //左根右
    if(x*2<=n)zx(x*2);
    cout<<a[x]<<' ';
    if(x*2+1<=n)zx(x*2+1);
}
inline void hx(int x)
{
    
    //左右根
    if(x*2<=n)hx(x*2);
    if(x*2+1<=n)hx(x*2+1);
    cout<<a[x]<<' ';
}
int main()
{
    
    
    cin>>n>>p;
     
    n=pow(2,n)-1;
    while(1)
    {
    
    
     int x;cin>>x;
     if(!vis[x])a[++k]=x,vis[x]=1;
     if(k>=n)break;//找到k个不同的树当节点
    }
    if(p==1)qx(1);//先序遍历
    else if(p==2)zx(1);//中序遍历
    else hx(1);//后序遍历
    return 0;
}


裁枝剪枝在这里插入图片描述

树形dp用dp[i][1/0]表示以i为根节点的树i要不要选的最大价值,如果这个根要选,那么递归儿子,如果要选,如果儿子代价>0那么加上儿子,不选,看看儿子要不要选

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    
    
    int f=1,res=0;
    char ch=getchar();
    while(!isdigit(ch)){
    
    if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){
    
    res=(res<<1)+(res<<3)+(ch&15);ch=getchar();}
    return res*f;
}
int n,f[550000][2],head[550000],tot,a[17000];
struct node
{
    
    
    int u;
    int v;
}edge[550000];
inline void add(int x,int y)
{
    
    
    edge[++tot].u=head[x];
    edge[tot].v=y;
    head[x]=tot;
}
inline void dfs(int x,int y)
{
    
    
    f[x][1]=a[x];
    f[x][0]=0;
    for(int i=head[x];i;i=edge[i].u)
    {
    
    
        int to=edge[i].v;
        if(to!=y)
        {
    
    
            dfs(to,x);
            if(f[to][1]>0)f[x][1]+=f[to][1];//要选,看看要不要儿子
            f[x][0]=max(f[x][0],max(f[to][0],f[to][1]));//不选看看要不要儿子
        }
    }
}
int main()
{
    
    
    n=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<n;i++)
    {
    
    
        int x,y;
        x=read();y=read();
        add(x,y);
        add(y,x);
    }
    dfs(1,0);
    cout<<max(f[1][0],f[1][1]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yhhy666/article/details/108268208