O oitavo dia aprendendo Python --- recursão e recursão

1. Implementação recursiva de enumeração exponencial

insira a descrição da imagem aqui

Método de escrita 1: dfs

Este é um exemplo de programa para pesquisa em profundidade (DFS) para gerar todos os subconjuntos de comprimento 1 a n. Especificamente, o programa define uma função chamada dfs, que é usada para gerar todos os subconjuntos recursivamente. Em cada chamada recursiva, a função começa na posição atual u e tenta descer até a posição n+1. À medida que cada local é percorrido, a função adiciona esse local à lista de caminhos e, em seguida, chama recursivamente a função dfs para continuar a percorrer. Quando a posição n + 1 é alcançada, a função para a recursão e retorna. Ao final de cada chamada recursiva, a função remove o último elemento da lista de caminhos para que o subconjunto possa ser gerado adequadamente na próxima chamada recursiva.

Por fim, a função principal chama a função dfs(1) para gerar todos os subconjuntos de comprimento 1 a n e imprime cada subconjunto no console. Este programa é uma boa referência e prática para aprender o algoritmo DFS e o algoritmo de geração de subconjuntos.

n = (int)(input())
path = []
def dfs(u):
    print(" ".join(str(i) for i in path))
    if u == n + 1: return
    for i in range(u, n + 1):
        path.append(i)
        dfs(i + 1)
        path.pop()

dfs(1)

Método de escrita 2: função da biblioteca python

combinações(ls,i)

Retorna uma combinação de elementos de comprimento i selecionados de ls na ordem dos elementos em ls. Por exemplo, ls = ["1", "2", "3"], então as combinações (ls, 2) retornarão [("1", "2"), ("1", "3"), ( "2", "3")] Nesta lista, cada elemento é uma tupla com comprimento 2, o que significa que uma combinação de dois elementos é selecionada e a ordem desses dois elementos em ls não muda.

from itertools import *
n = int(input())
ls = []
for i in range(1,n+1):
    ls.append(str(i))
for i in range(n+1):
    for element in combinations(ls,i):
        a = " ".join(element)
        print(a)

Em segundo lugar, implementação recursiva da enumeração de permutaçãoinsira a descrição da imagem aqui

própria maneira de escrever

n=int(input())
st=[False]*10
path=[]
def f(u):
    if u==n:
        print(" ".join(str(i) for i in path))
    for i in range(1,n+1):
        if st[i]==False:
            st[i]=True
            path.append(i)
            f(u+1)
            st[i]=False
            path.pop()
f(0)

3. Implementação recursiva de enumeração combinada

insira a descrição da imagem aqui
própria maneira de escrever

n,m=map(int,input().split())
st=[False]*30
def f(u,t):
    if t==m:
        for i in range(1,len(st)):
            if st[i]==True:
                print(i,end=' ')
        print()
        return
    for i in range(u,n+1):
        if st[i]==False:
            st[i]=True
            f(i,t+1)
            st[i]=False
f(1,0)

4. Jogue as moedas

insira a descrição da imagem aqui

a,b=input(),input()
ans=0
a=[i for i in a]
b=[i for i in b]
for i in range(len(a)):
    if a[i]!=b[i]:
        a[i+1]=('o' if a[i+1]=='*' else '*')
        ans+=1
print(ans)

5. Cálculo de números

insira a descrição da imagem aqui

h=[0]*1000
n=int(input())
for i in range(1,n+1):
    h[i]=1
    for j in range(1,i//2+1):
        h[i]+=h[j]
print(h[n])

6. A mudança inexplicável

insira a descrição da imagem aqui
insira a descrição da imagem aqui

import copy
g=[[0 for i in range(5)]for j in range(5)]
gg = [[0 for i in range(5)]for j in range(5)]
n=int(input())
dx=[1,0,-1,0,0]
dy=[0,1,0,-1,0]
def turn(x,y):
    for i in range(5):
        x1=x+dx[i]
        y1=y+dy[i]
        if x1<0 or x1>=5 or y1<0 or y1>=5:
            continue
        if g[x1][y1]=='1':
            g[x1][y1]='0'
        else:
            g[x1][y1]='1'

for _ in range(n):
    for i in range(5):
        g[i]=list(input())
    if _<n-1:#读入换行符
        c=input()
    gg=copy.deepcopy(g)
    res=19999#记录答案,最小步数
    for x in range(32):#5个1,枚举每种变换情况
        stp=0
        for i in range(5):
            op=x>>i&1
            if op==1:
                turn(0,i)#先定第一排怎么改变的
                stp+=1
        for i in range(4):
            for j in range(5):
                if g[i][j]=='0':
                    turn(i+1,j)#如果这一行是灭的话,那么就按下一行的灯
                    stp+=1
        flag=1
        for i in range(5):
            if g[4][i]=='0':
                flag=0
                break
        if flag==1:
            res=min(res,stp)
        g=copy.deepcopy(gg)
    if res>6:
        print(-1)
    else:
        print(res)


7. Irmãos Pilotos


Acho que esse tipo de pergunta é quase compreensível. Essa pergunta é igual ao tipo de pergunta acima. Também me refiro à mesma pessoa que a escreveu. Acho que ele a escreveu com muita clareza!

import copy
g=[[0 for i in range(4)]for j in range(4)]
change = [[0 for i in range(4)]for j in range(4)]
dis=[]
ans=[]
def get(x,y):
    return 4*x+y

st=0
for i in range(4):
    g[i]=list(input())
    for j in range(4):
        if g[i][j]=='+':
            st+=1<<get(i,j)#记录现在的情况
for i in range(4):
    for j in range(4):
        for k in range(4):
            change[i][j]+=(1<<get(k,j))+(1<<get(i,k))#记录变化一个地方的改变
        change[i][j]-=(1<<get(i,j))
res=100
for i in range(1<<16):#多种不同的翻转方式
    now=st
    dis.clear()#记录路径
    for j in range(16):
        op=i>>j&1
        if op==1:
            x=j//4
            y=j%4
            now^=change[x][y]
            dis.append([x+1,y+1])
    if now==0 and len(dis)<res:
        res=len(dis)
        ans=copy.deepcopy(dis)
print(res)
for i,j in ans:
    print(i,j)

Oito, com pontuações

insira a descrição da imagem aqui
Para esta questão, acabei de ler dois métodos de escrita. Sinto que posso escrevê-lo na próxima vez quando ler o código python, mas se eu ler C++, acho que não devo ser capaz de escrevê-lo hahahaha

Então eu vi esses dois estilos de escrita e me sinto muito bem!

Método de escrita um:

Eu sinto que isso é muito semelhante ao arranjo completo, e então ele organizou os números por completo e depois

n = int(input())
ans = 0
used =[False for i in range(10)]
res = []
def check(res):
    a=0
    for i in range(0,len(res)-2):
        a=a*10+int(res[i])
        b=0
        if a<n:
            for j in range(i+1,len(res)-1):
                b=b*10+int(res[j])
                c=0
                for z in range(j+1,len(res)):
                    c=c*10+int(res[z])
                if (a+b/c)==n:
                    global ans
                    ans+=1

def backtrack(st):
    if st == 10:
        check(res)
        return
    for i in range(1,10):
        if used[i]:
            continue
        used[i] = True
        res.append(i)
        backtrack(st+1)
        res.pop()
        used[i] = False

backtrack(1)
print(ans)

Método de escrita dois:

n = int(input())


def dfs_c(a, c):
    b = c*(n-a)
    if len(str(b)+str(a)+str(c))>9: return

    if set('123456789')==set(str(a)+str(b)+str(c)) and len(str(b)+str(a)+str(c))==9:
        global res
        res += 1

    for i in range(1, 10):
        if i not in use:
            use.add(i)
            dfs_c(a, c*10+i)
            use.remove(i)

def dfs_a(a):
    if a>=n:
        return
    if a:
        dfs_c(a, 0)

    for i in range(1, 10):
        if i not in use:
            use.add(i)
            dfs_a(a*10 + i)
            use.remove(i)


res = 0
use = set()
dfs_a(0)
print(res)

nove, tijolos

insira a descrição da imagem aqui
A seguir, mostrarei várias formas diferentes de escrever, e acho todas muito boas!

Método de escrita um:

Este método não é a solução ideal, mas acho que seu método de escrita é ótimo e vale a pena aprender!
lei da violência

change={
    
    'B':'W','W':'B'}
for _ in range(int(input())):
    N=int(input())
    line=list(input())[:N]
    if 'W' not in line or 'B' not in line:
        print('0')
    else:
        result=[]
        for i in range(N-1):
            if line[i]=='B':
                line[i],line[i+1]='W',change[line[i+1]]
                result.append(i+1)
        if line[-1]=='W':
            print(f"{
      
      len(result)}\n{
      
      ' '.join(map(str,result))}")
        else:#如果最后不是W,说明要翻转B
            for i in range(N-1):
                if line[i]=='W':
                    line[i],line[i+1]='B',change[line[i+1]]
                    result.append(i+1)
            if line[-1]=='B':
                print(f"{
      
      len(result)}\n{
      
      ' '.join(map(str,result))}")
            else:print('-1')

Método de escrita dois:

é a solução ótima

t=int(input())
def getcnt(pos,arr):
    res,en=0,[]
    for i in range(len(arr)-1):
        if arr[i]==1-pos:
            arr[i]=pos
            arr[i+1]=1-arr[i+1]
            res+=1
            en.append(i+1)
    return (1000,-1)if arr[len[arr]-1]!=pos else (res,en)
for _ in range(t):
    n=int(input())
    a=input()
    b=[1 if i=='W' else 0 for i in a]
    c=b[:]
    left=[getcnt(0,c),getcnt(1,b)]#讨论两种情况,全部反转为'w',或者全部反转为'B'
    left.sort(key=lambda x:x[0])#按照第一个关键词排序
    if left[0][0]<10000:
        print(left[0][0])
        for i in left[0][1]:
            print(i,end=' ')
        print()
    else:
        print(-1)

Dez, passagem de número

insira a descrição da imagem aqui
insira a descrição da imagem aqui
Primeiro, o código obtém os resultados da travessia pós-ordem e da travessia em ordem da árvore binária por meio da entrada e usa um dicionário para registrar as posições de cada nó nos resultados da travessia em ordem percorrendo os resultados da travessia em ordem, de modo que cada nó possa ser encontrado nos resultados da travessia pós-ordem.A posição do nó no resultado da travessia inordem determina o alcance das subárvores esquerda e direita.

Em seguida, o código cria uma fila para passagem em largura da árvore binária. Inicialmente, o intervalo de toda a árvore binária é adicionado à fila, cada vez que um intervalo é retirado da fila e o último nó na o resultado da travessia pós-ordem é usado como o nó raiz e, em seguida, encontre a posição do nó raiz no resultado da travessia em ordem no dicionário para determinar o intervalo da subárvore esquerda e da subárvore direita. subárvore não estiver vazia, adicione o intervalo da subárvore esquerda à fila. Se o intervalo da subárvore direita Se o intervalo da árvore não estiver vazio, adicione o intervalo da subárvore direita à fila e, finalmente, adicione o nó raiz ao lista de resultados.

Por fim, o código separa os números na lista de resultados com espaços e os exibe como resultado da travessia de pré-ordem.

from collections import deque

N = int(input())
postOrder = [*map(int, input().split())]
inOrder = [*map(int, input().split())]
find = {
    
    }
for i, inOrder_i in enumerate(inOrder):
    find[inOrder_i] = i

que, result = deque([(0, N-1, 0, N-1)]), []
while que:
    post_l, post_r, in_l, in_r = que.popleft()
    root_value = postOrder[post_r]
    in_i = find[root_value]
    l_len, r_len = in_i - in_l, in_r - in_i
    if l_len:
        que.append((post_l, post_l + l_len - 1, in_l, in_i - 1))
    if r_len:
        que.append((post_r - r_len, post_r - 1, in_i + 1, in_r))
    result.append(str(root_value))
print(' '.join(result))

Método de escrita 2: bfs

n = int(input())

a = list(map(int, input().split()))
b = list(map(int, input().split()))
lc = [0]*(n+1)
rc = [0]*(n+1)

def p(l, r):
    if len(l) == 1:
        return l[0]
    elif len(l) == 0:
        return 0
    i = 0
    while l[i] != r[-1]:
        i += 1
    v = l[i]

    rc[v] = p(l[i+1:], r[i:-1])
    lc[v] = p(l[:i], r[0:i])
    return v

def bfs(x):
    q = []
    q.append(x)
    print(x, end = ' ')

    while q:
        t = q.pop(0)
        if lc[t]:
            q.append(lc[t])
            print(lc[t], end = ' ')
        if rc[t]:
            q.append(rc[t])
            print(rc[t], end = ' ')
        # print(q)

p(b, a)

bfs(a[-1])

Acho que você gosta

Origin blog.csdn.net/qq_51408826/article/details/129447740
Recomendado
Clasificación