简单计算:
1.阶乘n!
int factorial(int n)
{
if(n<=1) return n;
return n*factorial(n-1);
}
阶乘(非递归方法):
int factorial(int n)
{
int sum = 1;
while(n>1){
sum*=n;
n--;
}
}
计算累加和:计算1+2+3+…+n
int get_sum(int n)
{
if(n==1) return 1;
return n+get_sum(n-1);
}
2.斐波那契;
int fib(int n)
{
if(n<=1) return n;
return fib(n-1)+fib(n-2);
}
3.排列①:m个A和n个字母B能排列多少个组合?
int dfs(int m,int n)
{
printf("m=%d,n=%d\n",m,n);
if(m==0||n==0) return 1;
return dfs(m-1,n)+dfs(m,n-1);
}
排列②:全排列
(1)C++STL全排列函数next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数;
此外,next_permutation(node,node+n,cmp)可以对结构体num按照自定义的排序方式cmp进行排序。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int num[3]={1,2,3};
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+3));
return 0;
}
/*
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
*/
(2)手写递归:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N = 100;
int p[N];
bool vis[N];
int ans = 0;
int n;
void print()
{
for(int i = 1; i <= n; i++){
printf("%d ",p[i]);
}
printf("\n");
}
void dfs(int s)
{
if(s==n+1){
ans++;
print();
return;
}
for(int i = 1; i <= n; i++){
if(!vis[i]){
p[s] = i;
vis[i] = true;
dfs(s+1);
vis[i] = false;
}
}
}
int main()
{
printf("请输入一个小于100的正整数:");
scanf("%d",&n);
dfs(1);
cout << ans;
return 0;
}
4.n个球,任取m个不放回,问有多少种取法
int dfs(int n,int m)
{
printf("%d,%d\n",n,m);
if(n<m) return 0;
if(n==m||m==0) return 1;//注意m=0时也有一种取法
return dfs(n-1,m)+dfs(n-1,m-1);//该球不取,则继续从n-1个球中取m个;若取,则继续从n-1个球中取m-1个
}
5.反序输出
①字符串翻转
void rev(string s)
{
if(s.size()>1){
rev(s.substr(1,s.size()));
}
cout << s[0];
}
②整数倒序输出
void rev(int n)
{
if(n==0) return;
cout << n%10;
rev(n/10);
}
6.爬楼梯:一步只能迈1或2个台阶,第一步迈左脚,然后左右交替,最后一步迈右脚。(即一共要走偶数步)
问有多少种走法?
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int ans = 0;
void dfs(int step,int flag)
{
if(step==39&&flag%2==0){
ans++;
return;
}
if(step>39) return;
dfs(step+1,flag+1);
dfs(step+2,flag+1);
}
int main()
{
dfs(0,0);//1,1开始是错误答案,因为第一步也可以迈两步
cout << ans;
return 0;
}
/*
ans=51167078
*/
或:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int dfs(int step,int flag)
{
if(step==0&&flag%2==0){
return 1;
}
if(step<0) return 0;
return dfs(step-1,flag+1)+dfs(step-2,flag+1);
}
int main()
{
cout << dfs(39,0);//1,1开始是错误答案,因为第一步也可以迈两步
}
7.折半查找(二分查找)
int Find(int a[],int k,int low,int high)
{
int i,mid;
if(low>high)
i=-1;
else
{
mid=(low+high)/2;
if(a[mid]==k)
i=mid;
else if(a[mid]<k)
i=Find(a,k,mid+1,high);
else
i=Find(a,k,low,mid-1);
}
return i;
}
8.汉诺塔
void move(char X,char Y)
{
printf("move:%c->%c\n",X,Y);
}
//将n个圆盘由A移到C,并且排列顺序不变(即由上至下为由小至大
void hanoi(int n,char A,char B,char C)
{
if(n==1){
move(A,C);
return;
}
hanoi(n-1,A,C,B);//先将n-1个圆盘由A移动到B,借助C
move(A,C);//再将第n个圆盘由A移动至C
hanoi(n-1,B,A,C);//最后将n-1个圆盘由B移动到C,借助A;则完成了由A->C的移动
}
9.猴子吃桃
有一只猴子摘了一大堆桃子吃,它按照这样的规律吃桃子:第一天吃一半多一个,第二天吃第一天剩余的一半多一个,第三天吃第二天剩余的一半多一个…以此类推,当第七天时,恰好只剩下一个桃子。求猴子一共摘了多少个桃子?
n:表示第几天 F(n):表示第n天有多少个桃子
F(7) = 1
F(6) = ( F(7) + 1 ) * 2
F(5) = ( F(6) + 1 ) * 2
F(4) = ( F(5) + 1 ) * 2
…
F(n) = ( F(n+1) + 1 ) * 2
通过上面一系列的表达式,可以发现递归结构的两个关键信息
递归通项式:F(n)=(F(n+1) + 1) * 2
递归终止情况:F(7) = 1
int dfs(int n)
{
if(n==7) return 1;
return 2*(dfs(n+1)+1);
}
10.十进制转二进制输出:
//n为正整数
void dec2bin(int n)
{
if(n==0) return;
dec2bin(n/2);
cout << n%2;
}
11.求组成一个正整数的所有数字之和
int get_sum(int n)
{
if(n==0) return 0;
return n%10+get_sum(n/10);
}
12.n^k递归实现
int power(int n,int k)
{
if(n==0) return 0;
if(k==0) return 1;
if(k==1) return n;
return n*power(n,k-1);
}
补充:整数的快速幂运算
13.求最大公约数(辗转相除法)
int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
14.求最小公倍数
①最小公倍数=两数乘积/最大公约数
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
②穷举法
//需满足a<=b
int lcm(int a,int b)
{
for(int i = b; ; i+=b){
if(i%a==0) return i;
}
}
15.回文串判断
bool judge(string s)
{
if(s.size()==1||s.size()==0) return true;
if(s[0]!=s[s.size()-1]) return false;
return judge(s.substr(1,s.size()-2));
}
以上均为楼主自己测试写的代码,若有不完美之处,请大家指正!