- 1. Implementação recursiva de enumeração exponencial
- 2. Implementação recursiva da enumeração de permutação! [Insira a descrição da imagem aqui] (https://img-blog.csdnimg.cn/bfd48628fb0c495bbbd2aeea695d4b7e.png)
- 3. Implementação recursiva de enumeração combinada
- 4. Jogue as moedas
- 5. Cálculo de números
- 6. A mudança inexplicável
- 7. Irmãos Pilotos
- Oito, com pontuações
- nove, tijolos
- Dez, passagem de número
1. Implementação recursiva de enumeração exponencial
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ção
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
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
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
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
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
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
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
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])