代码拉取完成,页面将自动刷新
# -*- coding: utf-8 -*-
# @project : 《Atcoder》
# @Author : created by bensonrachel on 2021/9/8
# @File : D - KAIBUNsyo(回文序列,图,连通分量,BFS).py
import sys
sys.setrecursionlimit(80000)
#py需要80000、python3要1000000
def dfs(v):
"""
涉及递归的问题一定要考虑递归深度的问题,不然会导致RE!!!
:param v:
:return:
"""
if (not flag[v]):
return 0
flag[v] = False
for vv in table[v]:
dfs(vv)
"""
这不是一道字符串的题目,是一道图论问题,求无向非连通图的遍历和计数。
连通分量里面一定是不相等的数字。求每个连通分量的元素个数-1的和
从数组两边开始遍历,都是每次走一步,遇到相同的就是自己一个是一个连通分量
遇到不同的就是会有两个数嘛,然后这两个数组成一个连通分量
后面的遍历也是如此,有相同的就加原有的连通分量,没有和之前的相同的就独自为一个连通分量
为什么每个连通分量的元素个数-1就是这个连通分量的操作次数?
因为这里面的k个数字最后都要变成同一个数,,所以至少要做k-1次操作,
为什么这个操作就等于
“Choose a pair (x,y) of positive integers, and replace every occurrence of x in A with y.”
疑问是:不是已经把数组其他地方有这个数的地方都改变了吗。有点绕。
因为这是不同的数字才会进来,也因为是不同的数字,所以需要做一次操作,
如果前面已经做了操作的改变了的,后面有可能也就不会遇到,也就不会再进入连通分量了,
所以就是有多少个不同的,就做 多少个减一 次操作才能把他们都变成一样。
"""
if __name__ == '__main__':
n = int(input())
flag = [False] * (200005)#标记数组,一种数字标记一次即可,用字典也行,但是有一个用例会超时。因为(*)处,所以直接用数组即可,也不大。
#标记是否被遍历过。
a = []
ans = 0
for i in input().split():
a.append(int(i))
if (not flag[int(i)]):#(*)
flag[int(i)] = True
ans += 1
table = [list() for i in range(200005)]
for i in range((n - 1) // 2 + 1):#邻接表
table[a[i]].append(a[n - 1 - i])
table[a[n - 1 - i]].append(a[i])
for i in range(200005):#遍历每个连通分量
if (flag[i]):
ans -= 1
dfs(i)
print(ans)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。