算法-递归
例子1 全排列 n!
#include <iostream> using namespace std; void swap(int& a,int& b){ int r=a; a = b; b=r; } //将数组 第begin个数到第end个数之间的数进行全排列输出 void permutation(int* list,int begin, int end){ if(begin==end){ //第end个数已经排好 可以输出了 for(int i=0;i<end;i++){ cout<<list[i]<<","; } cout<<endl; return; } for(int i=begin;i<end;i++){ swap(list[begin],list[i]); permutation(list,begin+1,end); swap(list[i],list[begin]); //恢复数组原样 } } int main(){ int n; int list[10]={1,2,3,4,5,6,7,8,9,0}; cin>>n; permutation(list,0,n); for(int i=0;i<10;i++){ cout<<list[i]<<" "; } }
例子2:逆波兰表达式
#include <iostream> using namespace std; //逆波兰表达式 double exp(){ char r[10]; scanf("%s",r); //遇空格断开 switch(r[0]){ case '+': return exp() + exp(); case '-': return exp() - exp(); case '*': return exp() * exp(); case '/': return exp() / exp(); default: return atof(r); } } int main(){ double ans; ans = exp(); cout<<ans; }
#include <iostream> using namespace std; //逆波兰表达式 转化为普通表达式 void exp(){ char r[10]; scanf("%s",r); //遇空格断开 switch(r[0]){ case '+': cout<<"(";exp();cout<<"+";exp();cout<<")"; break; case '-': cout<<"(";exp();cout<<"-";exp();cout<<")"; break; case '*': cout<<"(";exp();cout<<"*";exp();cout<<")";break; case '/': cout<<"(";exp();cout<<"/";exp();cout<<")";break; default: cout<<r; } } int main(){ exp(); }
例子3 普通表达式的计算
#include <iostream> using namespace std; //表达式的常规计算 //基本思想 : 表达式由项组成(以+或-连接起来的不同部分) //项由因子组成(以*或/连接起来的不同部分) //因子又是由数字或表达式组成的,表达式由括号扩着 //数字和数字之间可以直接计算 double expValue(); double factorValue(){ //读入并计算一个因子的值 double v; char c = cin.peek(); if(c=='('){ //在括号里面说明是表达式 cin.get(); v = expValue(); cin.get(); } else{ cin>>v; } return v; } double itemValue(){ //读入并计算项的值 double v=factorValue(); while(1){ char c=cin.peek(); if(c=='/'){ cin.get(); v /= factorValue(); } else if(c=='*'){ cin.get(); v *= factorValue(); } else{ break; } } return v; } double expValue(){ //计算表达式的值 double v=itemValue(); while(1){ //重复提取计算符号和表达式 char c= cin.peek(); if(c=='+'){ cin.get(); v += itemValue(); } else if(c=='-'){ cin.get(); v -= itemValue(); } else{ break; } } return v; } int main(){ cout<<expValue()<<endl; }
例子4:分割棋盘
#include <iostream>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
//棋盘分割 每个棋格都代表一个数
//用一刀切法 切割指定次数 分割给定的正方形棋盘 ,分成的矩形小棋盘的值是其所有格子之和
//求使得各矩形小棋盘总分的均方差最小值
//分析问题 大棋盘是给定的,n也是给定的 所以无论怎么分 分成的矩形小棋盘总分的均值总是相同的
//各矩形小棋盘只由 各个小棋盘的总分平方和决定
//因此问题转化为 求将一个给定的棋盘分成指定个矩形,矩形的总分的平方和最小为多少。
//给每个格子(x,y)坐标
int sum[9][9];//sum(i,j)是棋盘(1,1)到(i,j)的总分
int result[16][9][9][9][9];//result(n,x1,y1,x2,y2)是将(x1,y1)和(x2,y2)构成的矩形分成n块,的最小值
int smallsum(int x1,int y1,int x2,int y2){ //(x1,y1)到(x2,y2)的总分
return sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
}
int fun(int n,int x1,int y1,int x2,int y2){
//以(x1,y1)为左定点,(x2,y2)为右定点的矩形,分成n个矩形后 最小的平方和
//中止条件 横向最多切 x2-x1 , 纵向最多y2-y1, 必须切n-1,所以x2-x1+y2-y1>=n-1
int v = 1<<30;
if(n==1){
int t=smallsum(x1,y1,x2,y2);
return t*t;
}
if(x2-x1+y2-y1<n-1){
return v;
}
if(result[n][x1][y1][x2][y2]!=-1){
return result[n][x1][y1][x2][y2];
}
//对 x1-x2之间所有能切的的切法进行遍历
for(int x=x1;x<x2;x++){
int left=smallsum(x1,y1,x,y2);
int right=smallsum(x+1,y1,x2,y2);
int t=min(fun(n-1,x+1,y1,x2,y2)+left*left,fun(n-1,x1,y1,x,y2)+right*right);
v = min(v,t);
}
//对y1-y2之间所有能切的切法进行遍历
for(int y=y1;y<y2;y++){
int up=smallsum(x1,y1,x2,y);
int down=smallsum(x1,y+1,x2,y2);
int t=min(fun(n-1,x1,y1,x2,y)+down*down,fun(n-1,x1,y+1,x2,y2));
v = min(v,t);
}
result[n][x1][y1][x2][y2] = v;
return v;
}
int main(){
int n;
memset(sum,0,sizeof(sum));//置0
memset(result,0xff,sizeof(result));//置-1
cin>>n;
for(int i=1;i<=8;i++){
int rowsum = 0;
for(int j=1;j<=8;j++){
int s;
cin>>s;
rowsum +=s;
sum[i][j]=sum[i-1][j]+rowsum; //上一行以上的矩形+ 本行的矩形
}
}
//输出均方差
int squareSum = fun(n,1,1,8,8);
double result = n*squareSum - sum[8][8]*sum[8][8];
cout<<setiosflags(ios::fixed) << setprecision(3) <<sqrt(result/(n*n));
}
例5.放苹果问题
#include <iostream> #include <cmath> #include <cstring> #include <iomanip> using namespace std; //放苹果问题 将m个苹果放到n个盘子里,允许有的盘子空着不放 int appway(int m,int n){ if(m==0){ return 1; } if(n==0){ return 0; } if(n>m){ return appway(m,m); } //下面处理盘子数目小于等于苹果数的情况 return appway(m,n-1)+appway(m-n,n); } int main(){ int m,n; cin>>m>>n; cout<<appway(m,n); }