clllll  

第一道题。递归,感染问题, 太激动了。考试的时候没做出来。太急躁了。想在感染的时候就求出来,这样不好。
先感染后求值。这样就简单了。

题目就是一个二维数组, 求单入口连通区域最大值。入口只能从边缘入‘O’进去,'O' 代表连通的。‘X’代表不连通
如果连通的区域还有'O'在边缘,那么就不算

  • 输入:
    第一行输入: 输入的是 m n, m代表行, n代表列。
    接下来的输入就是二维数组。

  • 输出:
    1:如果最大的单入口区域只有一个,那么输出坐标 和 通区域最大值是多少
    2:如果没有入口,输出 None
    3: 如果有多个,那么输出 个数和 最大值。

  • 例子1:
    4 4
    X X X X
    X O O X
    X O O X
    X O X X
    输出:3 1 5
    说明 3 1 是 坐标 5 是最大值

  • 例子2:
    5 4
    X X X X
    X O O O
    X X X X
    X O O O
    X X X X
    输出: 2 3
    说明:2是 有2个最大连通区域。 3是最大值

  • 例子3:
    6 4
    X X X X
    X O O O
    X X X X
    X O O O
    X X X X
    X X X O
    输出:2 3
    说明:2是 有2个最大连通区域。 3是最大值

  • 例子4:
    6 4
    X X X X
    X O O X
    X X X X
    X O O X
    X X X X
    X X X O
    输出:5 3 1
    说明 5 3 是坐标, 1是最大值。

代码:

m, n = map(int,input().split())
cell = [] 
for i in range(m):
    cell.append(input().split())
print(cell)
# 感染函数,先感染后计算。别感染的时候就想要结果。咱不行,咱慢慢来。
def fun(cell, i, j, infect):
    # cell,  i 和 j是当前要感染的位置 。infect是感染的值,是感染起始位置的坐标(i,j) 
    # 递归结束条件
    print("感染:",i, j, infect)
    if i < 0 or i > m -1 or j < 0 or j > n - 1:
        return  
    if cell[i][j] == 'O':
        # 如果当前位置是 O 就 感染 
        cell[i][j] = infect 
        # 分别从四个方向开始 感染 
        fun(cell, i + 1, j, infect)
        fun(cell, i - 1, j, infect)
        fun(cell, i, j + 1, infect)
        fun(cell, i, j - 1, infect)
    else:
        # 如果当前位置是 X 就 终止感染
        return  

#  分别遍历第一行 最后一行 第一列 最后 一列 。查找入口 

rukou = [] 
# 遍历第一行 感染 
for i in range(n):
    # 如果当前是 O就开始感染。
    print("第一行:",(0,i))
    if cell[0][i] == 'O':
        fun(cell, 0, i, (0, i))
        rukou.append((0, i))

# 遍历最后一行感染
for i in range(n):
    print("最后一行:",(m-1, i))
    if cell[m-1][i] == 'O':
        fun(cell, m-1, i, (m-1, i))
        rukou.append((m-1, i))

# 遍历第一列感染 
for i in range(m):
    print("第一列:", (i, 0))
    if cell[i][0] == 'O':
        fun(cell, i, 0, (i, 0))
        rukou.append((i, 0))

# 遍历最后一列感染
for i in range(m):
    print("最后一列:", (i, n-1))
    if cell[i][n-1] == 'O':
        fun(cell, i, n - 1, (i, n-1))
        rukou.append((i, n -1))

print("感染之后: ", cell)

print("入口点:", rukou)

d = {} 
for i in rukou:
    d[i] = 0 

print(d)


# 遍历
for i in range(m):
    for j in range(n):
        if cell[i][j] != 'X' and cell[i][j] in d.keys():    
            if  i == 0 or i == m -1 or  j == 0 or j == n -1:
                # 如果当前点在边缘 ,但是 坐标 和 i,j 不等。说明不符合。移除
                if (i, j) != cell[i][j]:
                    d.pop((i,j))
                else:
                    d[cell[i][j]] = d[cell[i][j]] + 1  
            else:
                d[cell[i][j]] = d[cell[i][j]] + 1 

print(d)
print(len(d))
print(len(d.keys()))

d2 = [] 

for key, value in d.items():
    d2.append((key[0], key[1], value))
print(d2)




if len(d2) == 0 :
    # 没有入口 
    print("None")

elif len(d2) == 1:
    # 如果d只有一个,直接打印坐标和个数
    item = d2[0]
    print("%s %s %s" % (item[0], item[1], item[2]) )
else:
    # d有多个。排序
    
    d2 = sorted(d2, key=lambda x: (x[2]), reverse=True)
    
    print(d2)
    max_count = 0 
    d3 = [] # 只保留最大的
    for item in d2:
        if item[2] >= max_count:
            # 
            d3.append(item)
            max_count = item[2]
	print(d3)
    print("%s %s" % (len(d3), d3[0][2]) )

考挂了总结:
第一:太菜了
第二:太想一步到位了。 感染的时候别急着算结果。先感染在说。不然递归返回很难处理。
第三:考完之后没有压力做,但是 遍历 第一行第一列 最后一行最后一列 的 索引还是容易搞错。

挂了就挂了。说明自己不行,继续努力。

posted on 2023-03-11 14:59  llcl  阅读(89)  评论(0编辑  收藏  举报