《算法竞赛进阶指南》 树形地铁系统

一些主要城市拥有树形的地铁系统,即在任何一对车站之间,有且只有一种方式可以乘坐地铁。

此外,这些城市大多数都有一个中央车站。

想象一下,你是一名在拥有树形地铁系统的城市游玩的游客,你想探索该城市完整的地铁线路。

你从中央车站出发,随机选择一条地铁线,然后乘坐地铁行进。

每次到达一个车站,你都将选择一条尚未乘坐过的地铁线路进行乘坐。

如果不存在未乘坐过的线路,则退回到上一个车站,再做选择。

直到你将所有地铁线路都乘坐过两次(往返各一次),此时你将回到中央车站。

之后,你以一种特殊的方式回忆自己的坐车过程,你将你的完整地铁乘坐路线编码为一个二进制字符串。

其中 00 编码表示你乘坐地铁线路到达距离中央车站更远的一站,11 编码表示你乘坐地铁线路到达距离中央车站更近的一站。

输入格式

第一行输入一个正整数 nn,代表测试用例数量。

每个测试用例由两行组成,每行输入一个由字符 00 和 11 构成的字符串,长度最多为 30003000, 两个字符串都描述了一种树形地铁系统的正确探索路线。

输出格式

对于每个测试用例,如果两个字符串描述的探索路线可以视为同一个地铁系统的两种探索路线,则输出 same

否则,输出 different

每行输出一个结果。

输入样例:

2
0010011101001011
0100011011001011
0100101100100111
0011000111010101

输出样例:

same
different

 

性质:若两课数同构,则说明他们的最小表示相同;
所以我们只要求得两棵树的最小表示,若相同则说明他们是同构的 

#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

string get(string &str, int &u)
{
    u ++ ;//记住这里跳过了下去的时候的0;
    vector<string> ans;
    while (str[u] == '0') ans.push_back(get(str, u));
    u ++ ;//为求最小表示,先除去往上走的节点,将其放在最后。
    
    string res = "0";//加上下去的时候的0
    sort(ans.begin(), ans.end());
    for (auto s : ans) res += s;//加上他的所有子树的最小表示
    res += '1';//把除去的往上走的节点加上;
    
    return res;
    
}

int main()
{
    int T;
    cin >> T;
    while (T -- )
    {
        string a, b;
        cin >> a >> b;
        a = '0' + a + '1';//给根节点加一条边,设置边界
        b = '0' + b + '1';
        int as = 0, bs = 0;
        if (get(a, as) == get(b, bs)) puts("same");
        else puts("different");
    }
    
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

啥也不会hh

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

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

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

打赏作者

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

抵扣说明:

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

余额充值