当前位置:   article > 正文

第十五届蓝桥杯Python大学B组国赛/决赛 I题题解_python蓝桥杯国赛题目

python蓝桥杯国赛题目

大概题目

某国王要给n个岛之间修桥,桥是双向的,国王可以将a岛和b岛连接起来,也可以将两座岛的桥炸掉,国王想知道经过一系列操作之后两座岛之间是否连接。

输入:岛屿数量n,每行第一个数是选择,1 是 合并,然后再输入两个岛屿a和b,输入 2 是炸掉最近一次合并的桥,如果没有桥就不需要任何操作,后面不需要岛屿a和b,如果输入 3 进行查询a与b是否相连。输入不是1,2,3则结束。

输出:两座岛是否连接,“ Yes ” or “ No ”。

输入样例:

5
1 2 3
1 3 4
2
3 3 4
1 2 5
3 3 5
4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出样例:

No
Yes
  • 1
  • 2

可撤销并查集可以做,但是为了简便直接利用python的特性(可以直接将每个合并操作之后的父数组保存)

思路:

用一个数组 st 记录父类数组 f 的值,每一次合并操作就将新的父类数组添加到st中,然后是 2 删除操作就将st最后一个删除,然后将新的最后一个值赋值给父类 f,然后其他就用并查集板子就行了。

st.append(f.copy())
  • 1

为什么在添加f的时候用了一个 copy() 操作:
st 列表中的所有元素都是对 f 列表的引用。因为 f 列表在每次修改后,其引用仍然指向同一个内存位置,所以 st 列表中的所有引用都会指向更新后的 f 列表。
所以每次 f 被修改时,st 中所有之前的数组也会跟着变化。
为了避免这种情况,在每次修改 f 后,将 f 的一个副本添加到 st 中,而不是直接添加 f。

全部代码:

n = int(input())
f = [0] + [i for i in range(1, n + 1)]

st=[f.copy()]
def find(a):
    if f[a] == a:
        return a
    f[a] = find(f[a])
    return f[a]
def unit(a, b):
    x = find(a)
    y = find(b)
    f[x] = y
f = [0] + [i for i in range(1, n + 1)]
while True:
    s=input()
    o=int(s[0])
    if o == 1:
        a=int(s[2]);b=int(s[4])
        unit(a, b)
        st.append(f.copy())
    elif o == 2:
        if len(st)>1:
            st.pop()
            f=st[-1]
    elif o == 3:
        a = int(s[2])
        b = int(s[4])
        x = find(a)
        y = find(b)
        if x == y:
            print('Yes')
        else:
            print('No')
    else:
        break

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/1013447
推荐阅读
相关标签
  

闽ICP备14008679号