阶乘

编辑切换为居中
添加图片注释,不超过 140 字(可选)

编辑切换为居中
添加图片注释,不超过 140 字(可选)
汉诺塔
问题背景
问题分析:
由于一次只能移动一个圆盘,且大的不能在小的上面(问题限制),因此直接将n个圆盘一次性由A移到C行不通。转移多个圆盘必须借助圆柱作为中转(辅助)。整体分析问题时,将n个圆盘由A移到C,必须将它上面的所有圆盘(前n-1个)由A移到B。才能将第n个由A移到C,最后将上面的n-1个由B移到C。
下面将整理一下思路。
首先明确递归函数的作用:将n个铜盘从A借助B移动到C。
接着三步走
将前n-1个由A移到B(只能借助C)
第n个由A移到C(不需借助圆柱)
将前n-1个由B移到C(只能借助A)
代码实现
#include<iostream>
using namespace std;
int n; // n个圆盘
void Hanoi(int n,char A,char B,char C) // 将n个圆盘借助B由A挪到C
{
if(n==1)
{
printf("将%d由 %c 移到 %c \n",n,A,C); // base case
return ;
}
Hanoi(n-1,A,C,B); // 将上面的n-1个借助C从A挪到B
printf("将%d由 %c 移到 %c\n",n,A,C); // 将第n个由A移到C(无需借助圆柱)
Hanoi(n-1,B,A,C); // 将上面的n-1个圆盘借助A移到C
}
int main()
{
scanf("%d",&n);
Hanoi(n,'A','B','C');
return 0;
}

编辑切换为居中
添加图片注释,不超过 140 字(可选)

编辑切换为居中
添加图片注释,不超过 140 字(可选)
指数型枚举
#include<iostream>
using namespace std;
void dfs(int x,int n,int num[])
{
if(x>n) // 边界情况
{
for(int i=1;i<=n;i++)
{
if(num[i]!=0)
cout<<num[i]<<" ";
}
cout<<endl;
return;
}
num[x]=NULL; // 当前位置不选数字
dfs(x+1,n,num);
num[x]=x;
dfs(x+1,n,num); // 当前位置选该数字
}
int main()
{
int n;
cin>>n;
int num[16];
dfs(1,n,num); // 从第一个位置开始枚举,共n个位置,存到数组num
return 0;
}

编辑切换为居中
添加图片注释,不超过 140 字(可选)
排列型枚举
#include<iostream>
using namespace std;
int st[10]; // 0表示不选,1表示选择
void dfs(int x,int n,int num[])
{
if(x>n)
{
for(int i=1;i<=n;i++)
cout<<num[i]<<" ";
cout<<endl;
return;
}
for(int i=1;i<=n;i++)
{
if(!st[i])
{
num[x]=i;
st[i]=1; // 标记使用该数
dfs(x+1,n,num); // 递归遍历下一位置
st[i]=0;
}
}
}
int main()
{
int n;
cin>>n;
int num[10];
dfs(1,n,num);
return 0;
}

编辑切换为居中
添加图片注释,不超过 140 字(可选)
组合型枚举
#include<iostream>
using namespace std;
int st[30];
void dfs(int x,int n,int m,int num[])
{
if(x>m)
{
for(int i=1;i<=m;i++)
cout<<num[i]<<" ";
cout<<endl;
return;
}
for(int i=1;i<=n;i++)
{
if(!st[i]&&i>=num[x-1])
{
num[x]=i;
st[i]=1;
dfs(x+1,n,m,num);
st[i]=0;
}
}
}
int main()
{
int n,m;
cin>>n>>m;
int num[30];
dfs(1,n,m,num);
return 0;
}

编辑切换为居中
添加图片注释,不超过 140 字(可选)