2023.1.6

P1229 遍历问题

题目描述

我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:

所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。

输入格式

输A数据共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。

输出格式

输出可能的中序遍历序列的总数,结果不超过长整型数。

输入输出样例

输入

abc

cba

输出

4


对先根遍历的每一个节点ali],在后根遍历中,找到一个b[j] ==a [ i]

判断: a [ i+1]是否等于b[j-1]

﹒如果是,则意味着找到了一个中跟遍历有两种的结构,ans*2

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4996)
#pragma warning(disable : 6031)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
char s1[1000], s2[1000];
int ans = 1;
int main()
{
    scanf("%s", s1);
    getchar();
    scanf("%s", s2);
    int len = strlen(s1) - 1;
    for (int i = 0; i <len; i++)
    {
        for (int j = len; j > 0; j--)
        {
            if (s1[i] == s2[j] && s1[i + 1] == s2[j - 1])
                ans=ans*2;
        }
    }
    printf("%d\n", ans);
    return 0;
}

P2078 朋友

题目背景

小明在 A 公司工作,小红在 B 公司工作。

题目描述

这两个公司的员工有一个特点:一个公司的员工都是同性。

A 公司有 NN 名员工,其中有 PP 对朋友关系。B 公司有 MM 名员工,其中有 QQ 对朋友关系。朋友的朋友一定还是朋友。

每对朋友关系用两个整数 (X_i,Y_i)(Xi,Yi) 组成,表示朋友的编号分别为 X_i,Y_iXi,Yi。男人的编号是正数,女人的编号是负数。小明的编号是 11,小红的编号是 -1−1。

大家都知道,小明和小红是朋友,那么,请你写一个程序求出两公司之间,通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。

输入格式

输入的第一行,包含 44 个空格隔开的正整数 N,M,P,QN,M,P,Q

之后 PP 行,每行两个正整数 X_i,Y_iXi,Yi

之后 QQ 行,每行两个负整数 X_i,Y_iXi,Yi

输出格式

输出一行一个正整数,表示通过小明和小红认识的人最多一共能配成多少对情侣(包括他们自己)。

输入输出样例

输入

4 3 4 2

1 1

1 2

2 3

1 3

-1 -2

-3 -3

输出

2

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4996)
#pragma warning(disable : 6031)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int a[100005], b[100005],n,m,p,q;
int finda(int v)
{
    if (a[v] == v) return v;
    a[v] = finda(a[v]);
    return finda(a[v]);
}
int findb(int x)
{
    if (b[x] == x) return x;
    b[x] = findb(b[x]);
    return findb(b[x]);
}
void uniona(int x, int y)
{
    if (x == 1 || a[x] == 1)
    {
        int t;
        t = x;
        x = y;
        y = t;
    }
    int root_x = finda(x);
    int root_y = finda(y);
    a[root_x] = root_y;
}
void unionb(int x, int y)
{
    if (x == 1 || b[x] == 1)
    {
        int t;
        t = x;
        x = y;
        y = t;
    }
    int root_x = findb(x);
    int root_y = findb(y);
    b[root_x] = root_y;
}
int main()
{
    scanf("%d%d%d%d", &n, &m, &p, &q);
    for (int i = 1; i <= n; i++)
    {
        a[i] = i;
    }
    for (int i = 1; i <= m; i++)
    {
        b[i] = i;
    }
    for (int i = 0; i < p; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        uniona(x, y);
    }
    for (int i = 0; i < q; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        x = x * -1;
        y = y * -1;
        unionb(x, y);
    }
    int man = 0;
    for (int i = 1; i <= n; i++)
    {
        if (finda(i) == a[1])
        man++;
    }
    int woman = 0;
    for (int i = 1; i <= m; i++)
    {
        if (findb(i) == b[1])
        woman++;
    }
    if (man > woman) printf("%d\n", woman);
    else printf("%d\n", man);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值