算法设计复习(一二递推递归)
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法设计复习(一二递推递归)相关的知识,希望对你有一定的参考价值。
第一章 算法概述
什么是算法:是对特定问题求解步骤的一种描述,是指令的有限序列。
算法的五个重要特性:输入、输出、有穷性、确定性、可行性
一个算法的优劣可以用时间复杂性和空间复杂性来衡量
算法和程序的关系
1.程序是使用某种程序设计语言对算法的具体实现,是对算法的精确描述,可在计算机上运行;
2.程序可以是无穷的,而算法必须是有穷的;
3.程序设计的核心是算法。
常用的描述算法的方法:自然语言、流程图、程序设计语言、伪代码等
排序算法:
直接插入排序:
第二章 STL简介
掌握有关vector的内容
vector(向量)从后面快速插入与删除,直接访问任何元素
vector和数组的区别
1.array 定义的时候必须定义数组的元素个数;而vector 不需要
2.array 定义后的空间是固定的了,不能改变;而vector 要灵活得多,可再加或减
3.vector有一系列的函数操作,非常方便使用
4.数组和vector不同,一个数组不能用另一个数组初始化,也不能将一个数组赋值给另一个数组;
知道set具有典型的特点: 内部的元素依据其值自动排序;set内的相同数值的元素只能出现一次
#include <bits/stdc++.h>
using namespace std;
int n;
map<string,int>mp;
int main()
while(cin>>n)
string tmp;
int g=0;
for(int i=1;i<=n;i++)
string k;
cin>>k;
mp[k]++;
if(mp[k]>g)
tmp=k,g=mp[k];
cout<<"answer:"<<tmp<<endl;
return 0;
了解有关“优先队列”的内容,关键是会使用优先队列去解决问题(默认情况下是使用大顶堆,是从大到小排列)
#include <bits/stdc++.h>
using namespace std;
struct cmp
bool operator()(int x,int y)
return x<y;
;
//priority_queue<int,vector<int>,greater<int>>q;
priority_queue<int,vector<int>,cmp>q;
int main()
int n;cin>>n;
for(int i=1;i<=n;i++)
int x;cin>>x;
q.push(x);
while(!q.empty())
cout<<q.top()<<endl;q.pop();
return 0;
STL其它内容不做要求
递推方法解决:
菲波那契数列:f[i]=f[i-2]+f[i-1]
汉诺塔移动次数:f(n)=2*f(n-1)+1
猴子吃桃:f[i]=2*f[i+1]+2
骨牌铺满方格
f(n)=f(n-1)+f(n-2) (n>2)
f(1)=1
f(2)=2
蜜蜂路线:f[i]=f[i-1]+f[i-2]
吃糖果:f[i] = f[i - 1] + f[i - 2]
昆虫繁殖:
b[i] = f[ i - x] * y; (成虫经过x月产卵 y个)
f[i] = f[ i - 1] + b[ i - 2]; (卵经过2个月长成成虫)
第3章 递归与分治策略
分治是一种算法思想,递归是实现这种思想的一种手段
n!
int fun(int n)
if(n==1)
return 1;
return n*fun(n-1);
菲波那契数列
#include <bits/stdc++.h>
using namespace std;
int n;
int fibo(int x)
if(x==1||x==2)
return 1;
return fibo(x-1)+fibo(x-2);
int main()
while(cin>>n)
cout<<"fibo["<<n<<"]="<<fibo(n)<<endl;
return 0;
猴子摘桃问题
#include <bits/stdc++.h>
using namespace std;
int n;
int fun(int x)
if(x==10)
return 1;
return 2*fun(x+1)+2;
int main()
cout<<"请输入想知道的第几天的桃子数目: ";
while(cin>>n)
cout<<"answer: "<<fun(n)<<endl;
return 0;
十进制转换为二进制
string s;
void fun(int n)
if(n==0)
return;
fun(n/2);
s+=n%2+'0';
int main()
cin>>n;
fun(n);
cout<<s<<endl;
return 0;
逆序(或正序)输出一个正数中的每一位数
void fun(int n)
if(n==0)
return;
s+=n%10+'0'; //逆序
fun(n/10);
//s+=n%10+'0'; //正序
集合的全排列
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],k=0;
void perm(int x)
if(x==n+1)
k++;
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
cout<<endl;
return;
for(int i=x;i<=n;i++)
swap(a[x],a[i]);
perm(x+1);
swap(a[x],a[i]);
int main()
cin>>n;
for(int i=1;i<=n;i++) a[i]=i;
perm(1);
cout<<k<<endl;
return 0;
递归求平方和函数(openjudge题目)
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],k=0,ans;
int fun(int n)
if(n==1)
return 1;
return n*n+fun(n-1);
int main()
cin>>n;
cout<<fun(n)<<endl;
return 0;
棋盘覆盖
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int tp,board[N][N];
void CB(int tr,int tc,int dr,int dc,int sz)
if(sz==1) return;
int t=++tp,s=sz/2;
//处理左上角
if(dr<tr+s&&dc<tc+s)
CB(tr,tc,dr,dc,s);
else
board[tr+s-1][tc+s-1]=t;
CB(tr,tc,tr+s-1,tc+s-1,s);
//处理右上角
if (dr < tr + s && dc >= tc + s) // 特殊方格在此棋盘中
CB(tr, tc+s, dr, dc, s);
else
board[tr + s - 1][tc + s] = t;
CB(tr,tc+s,tr+s-1,tc+s, s);
//处理左下角
if (dr >= tr + s && dc < tc + s) // 特殊方格在此棋盘中
CB(tr+s, tc, dr, dc, s);
else
board[tr + s ][tc + s-1] = t;
CB(tr+s,tc,tr+s,tc+s-1, s);
//处理右下角
if (dr >= tr + s && dc >= tc + s) // 特殊方格在此棋盘中
CB(tr+s, tc+s, dr, dc, s);
else
board[tr + s ][tc + s] = t;
CB(tr+s,tc+s,tr+s,tc+s, s);
int main()
CB(0,0,1,3,4);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
cout<<board[i][j]<<" ";
cout<<endl;
return 0;
找出这n个元素中第k小的元素(掌握线性时间选择法解决此问题)
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int n,a[N];
int select(int l,int r,int k)
if(l>=r) return a[l];
int pivot=a[l],i=l,j=r+1;
while(1)
doi=i+1;while(a[i]<a[pivot]);
doj=j-1;while(a[j]>a[pivot]);
if(i>=j) break;
swap(a[i],a[j]);
if(j-l+1==k)
return pivot;
a[l]=a[j];
a[j]=pivot;
if(j-l+1>k)
return select(l,j-1,k); //左半区找
else
return select(j+1,r,k-j+l-1); //右半区找
int main()
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
cout<<select(0,n-1,2)<<endl;
return 0;
半数集问题
int comp(int x)
int ans=1;
for(int i=1;i<=x/2;i++)
ans+=comp(i);
return ans;
int comp(int x)
if(a[x]) return a[x];
int ans=1;
for(int i=1;i<=x/2;i++)
ans+=comp(i);
a[x]=ans;
return ans;
整数因子分解问题
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int n,ans;
void fun(int x)
if(x==1)
ans++;return;
for(int i=2;i<=x;i++)
if(x%i==0)
fun(x/i);
int main()
cin>>n;
fun(n);
cout<<ans<<endl;
return 0;
汉诺塔移动次数:移动次数为(2^n-1)
#include <bits/stdc++.h>
using namespace std;
int x;
void move(char from ,char to)
x++;
cout<<"Move "<<from<<","<<to<<endl;
void hanoi(int n, char first, char second, char third)
if(n==1)
move(first,third);
return;
hanoi(n-1,first,third,second); //n-1个盘子通过第三个托到第二个托上
move(first,third);
hanoi(n-1,second,first,third);
int main()
int m;
cout<<"the number of diskes:";
cin>>m;
cout<<"move "<<m<<" diskes:\\n";
hanoi(m,'A','B','C');
cout<<"result: "<<x<<endl;
return 0;
n个数的划分:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],k=0;
void perm(int x)
if(x==n+1)
k++;
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
cout<<endl;
return;
for(int i=x;i<=n;i++)
swap(a[x以上是关于算法设计复习(一二递推递归)的主要内容,如果未能解决你的问题,请参考以下文章