title: 递推与递归经典问题的python实现
date: 2020-03-26 22:13:26
categories: 算法
tags: [python, 递推与递归]

## 递归实现指数型枚举

1≤n≤151≤n≤15

`3`

#### 输出样例：

`322 311 31 21 2 3`

#### 代码

`import sys,mathsys.setrecursionlimit(10**9)from collections import defaultdict IA = lambda: map(int,input().split())IAS= lambda: map(str,input().split())n=int(input())sta=[0 for i in range(n+1)]def dfs(i):    if i> n:        for i in range(n+1):            if sta[i]==1:                print(i,end=" ")        print()        return     sta[i]=0       dfs(i+1)        sta[i]=1    dfs(i+1)dfs(1)`

## 递归实现排列型枚举

1≤n≤9

`3`

#### 输出样例：

`1 2 31 3 22 1 32 3 13 1 23 2 1`

#### 代码

`import syssys.setrecursionlimit(10**9)n = int(input())st = [0 for i in range(n)]ways = []def dfs(u):    if u >= n:        for i in range(n):            print(ways[i] + 1, end = " ")        print()        return    for i in range(n):        if st[i] == 0:            st[i] = 1            ways.append(i)                        dfs(u + 1)            ways.pop()            st[i] = 0                        dfs(0)`
`n=input()n=int(n)path=[]def dfs(u,state):    if(u==n):        for each_path in path:            print(each_path,end=" ")        print()        return    for i in range(0,n):        if((state>>i&1)==0):            path.append(i+1)            dfs(u+1,state|1<<i)            path.pop()dfs(0,0)`

## 递归实现组合型枚举

#### 数据范围

n>0n>0 ,
0≤m≤n0≤m≤n ,
n+(n−m)≤25n+(n−m)≤25

`5 3`

#### 输出样例：

`1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5`

#### 代码

`IA = lambda:map(int, input().split())n, m = IA()res = []def dfs(u):    global n, m    # 剪枝    if len(res) > m or len(res) + (n - u) < m:        return        if u == n:        for it in res:            print(it + 1, end=" ")        print()    res.append(u)    dfs(u + 1)    res.pop()    dfs(u + 1)dfs(0)`
`n,m=map(int,input().split())ans=[0 for i in range(m+1)]def dfs(u,start):    if n-start+1<m-u+1:return     if u==m+1:        for i in range(1,m+1):            print(ans[i],end=" ")        print()        return             for i in range(start,n+1):        ans[u]=i        dfs(u+1, i+1)        ans[u]=0dfs(1,1)`

## 带分数

100 可以表示为带分数的形式：100=3+69258/714

1≤N<1061≤N<106

`100`

`11`

`105`

#### 输出样例2：

`6`

`m=int(input())n=9sta=[0 for i in range(n+1)]vis=[0 for i in range(n+1)]ans=0def f():    a=0    for i in range(1,n):        a=a*10+sta[i]        b=0        for j in range(i+1,n):            b=b*10+sta[j]            if b%a!=0:continue            c=0                 for k in range(j+1,n+1):                c=c*10+sta[k]            if  c+b//a ==m:                global ans                ans+=1def dfs(u):    if u>n:        f()        return     for i in range(1,n+1):        if vis[i]==1:continue        vis[i]=1        sta[u]=i        dfs(u+1)        vis[i]=0        sta[u]=0dfs(1)print(ans)`

n=a+b/c

b=nc-ac 先枚举a后枚举c

`m=int(input())n=9ans=0vis=[0 for i in range(n+1)]backup=[0 for i in range(n+1)]def f(a,c):    b=m*c-a*c    if b==0:return 0    backup=[x for x in vis]    while b:        x=b%10        if x==0 or backup[x]==1:return 0        backup[x]+=1        b//=10            #print(":"+str(vis))    for i in range(1,n+1):        if backup[i]!=1:            return 0        return 1def dfs_c(u,c,a):    if u>=n:return    if c:        if f(a,c)==1:            global ans            ans+=1    for i in range(1,n+1):        if vis[i]==0:            vis[i]=1            dfs_c(u+1,c*10+i,a)            vis[i]=0def dfs_a(u,a):    if u>=n:return    if a:dfs_c(u,0,a)    for i in range(1,n+1):        if vis[i]==0:            vis[i]=1            dfs_a(u+1,a*10+i)            vis[i]=0        dfs_a(1,0)print(ans)`

## 飞行员兄弟·

“飞行员兄弟”这个游戏，需要玩家顺利的打开一个拥有16个把手的冰箱。

1≤i,j≤41≤i,j≤4

#### 输入样例：

`-+-----------+--`

#### 输出样例：

`61 11 31 44 14 34 4`

#### 代码

`import copymp=[[] for i in range(0,4)]for i in range(0,4):    mp[i]=list(input())ans=[]path=[]minn=1e18def turn(x,y):    for i in range(0,4):        if mp[i][y]=='+':mp[i][y]='-'        else:mp[i][y]='+'            for j in range(0,4):        if mp[x][j]=='+':mp[x][j]='-'        else:mp[x][j]='+'            if mp[x][y]=='+':mp[x][y]='-'    else:mp[x][y]='+'def check():    for i in range(0,4):        for j in range(0,4):            if mp[i][j]=='+':                return 0    return 1def dfs(x,y,step):    #print(str(x)+" "+str(y))    if x>=3 and y>=4 :        if check()!=1: return        global minn,ans           if step<minn:            minn=step            ans=copy.deepcopy(path)            #print(ans)        return         if y==4:        y=0        x+=1        path.append([x,y])    step+=1    turn(x,y)        dfs(x,y+1,step)        turn(x,y)    path.pop()    step-=1    dfs(x,y+1,step)        dfs(0,0,0)print(minn)for it in ans:    print(str(it[0]+1)+" "+str(it[1]+1))`

## 翻硬币

#### 输入样例1：

`**********o****o****`

`5`

#### 输入样例2：

`*o**o***o****o***o**o***`

#### 输出样例2：

`1`
 难度：简单 时/空限制：1s / 64MB 总通过数：574 总尝试数：829 来源：第四届蓝桥杯省赛C++B组 算法标签
`s1=input()s2=input()le=len(s1)pre=-1ans=0for i in range(0,le):        if s1[i]!=s2[i]:        if pre==-1:            pre=i        else:            ans+=i-pre            pre=-1print(ans)`