一、欧几里得算法
求最大公约数的普通算法
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;//不需要判断n和m的大小,一次取余数计算就能交换大小
int r;
do
{
r=m%n;
m=n;
n=r;
}while(n!=0);
cout<<m;
return 0;
}
递归算法:
#include<iostream>
using namespace std;
int gcd(int,int);//函数
int main()
{
int n,m;
cin>>n>>m;
int r;
cout<<gcd(n,m);
return 0;
}
//递归实现
int gcd(int n,int m)//不需要判断n和m的大小,一次取余数计算就能交换大小
{
if(n%m==0)
return m;
else
return (m,n%m);
}
二、求n!的阶乘
算法分析:
想我们求5的阶乘,可以分解成5*4!,然后4!=4*3!。。。。。。。一直向下化简,直到1!=1,然后返回值
code:
#include<iostream>
using namespace std;
int f(int n);
int main()
{
int n;
cin>>n;
int fn=f(n);
cout<<fn;
return 0;
}
int f(int n)
{
if(n==0||n==1)//判断到达出口
return 1;
else
return n*f(n-1);
}
三、全排列问题
给定一个数字n,求1到你的全排列情况,并输出
典型的枚举递归算法,递归挨个检查数字是否使用,若没有使用,储存起来,继续下一个数字
code:
#include<iostream>
using namespace std;
int q[21];
bool a[21];//判断数组,检查这个数是否使用过
int n;//定义全局变量
void print();//输出结果
void dfs(int);
int main()
{
cin>>n;
dfs(1);
return 0;
}
void print()//输出结果
{
for(int i=1;i<n;++i)
cout<<q[i]<<" ";
cout<<q[n]<<endl;
}
void dfs(int m)
{
for(int i=1;i<=n;++i)
{
if(!a[i])
{
q[m]=i;//记录当前的数
a[i]=true;//标记已经使用过
if(m==n)
print();
else
dfs(m+1);//继续寻找下一个数字
a[i]=false;//回溯搜索
}
}
}
四、半数集问题
枚举递归与相加递归的结合
给定一个自然数n,由n 开始可以依次产生半数集
(1)、在n 的左边加上一个自然数,但该自然数不能超过最近添加的数的一半;
(2)、按此规则进行处理,直到不能再添加自然数为止
元素个数为f(n) ,则显然有:
code:
#include<iostream>
using namespace std;
int a[1001];
int comp(int n);
int main()
{
int n;
cin>>n;
cout<<comp(n);
return 0;
}
int comp(int n)//记忆化搜索
{
int ans=1;
if(a[n]>0)
return a[n]; //已经计算
for(int i=1;i<=n/2;i++)
ans+=comp(i);
a[n]=ans; //保存结果
return ans;
}