一.
1.题目:有一个兔子,从出生后第3个月起每个月都生一个兔子, 小兔子长到第三个月后每个月又生一个兔子,假如兔子都不死, 问每个月的兔子个数为多少?
2.思路:
我们先来模拟前几个月的兔子情况,括号内代表兔子月份,3个月以上不再增长。
月数 兔子情况 兔子数
1 1(1) 1
2 1(2) 1
3 1(3)+1(1) 2
4 1(3)+1(2)+1(1) 3
5 1(3)+1(3)+1(2)+1(1)+1(1) 5
6 1(3)+1(3)+1(3)+1(2)+1(2)+1(1)+1(1)+1(1) 8
... ... ...
可以观察到 ,随着月数1-6的增加,兔子数为1,1,2,3,5,8…观察兔子数,很明显是一个斐波那契数列。所以这个看起来很难的问题,本质就是求第n个斐波那契数。
3.代码:
递归写法:
#include <iostream>
using namespace std;
int Param(int n)
{
if(n<3)
return 1;
return Param(n-1)+Param(n-2);
}
int main()
{
int n;
while(cin>>n)
{
cout<<Param(n)<<endl;
}
return 0;
}
非递归写法:
#include <iostream>
using namespace std;
int Param(int n)
{
if(n<3)
return 1;
int sum1 = 1;
int sum2 = 1;
int sum = 0;
for(int i =2;i<n-2;i++)
{
sum = sum1+sum2;
sum2 = sum;
sum1 = sum2;
}
return sum;
}
int main()
{
int n;
while(cin>>n)
{
cout<<Param(n)<<endl;
}
return 0;
}
二.
1.题目:给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1。
输入描述:
输入包括两行,第一行代表字符串s1,第二行代表字符串s2
输入样例:
1AB2345CD
12345EF
输出:
2345
2.解题思路:用动态规划来完成,先定义一个二维数组,初始化为0,如果是第一行或第一列并且两个字符还相等的前提下,将该点的值改为1,如果不是第一行或者不是第一列,但两个相等,那么此时num[i][j]=num[i-1][j-1]+1,记录下这个点的值,以及横坐标。
下面是一个例子,abca字符串 ,abcbc字符串求最长公共子串。这是二位数组里的分布。
3.代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s1;
string s2;
while(cin>>s1>>s2)
{
int len1 = s1.size();
int len2 = s2.size();
int max = 0;
int end = 0;
vector<vector<int>>num(len1,vector<int>());
for(int i = 0;i<len1;i++)
{
num[i].resize(len2,0);初始化二维数组
}
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(s1[i]==s2[j])
{
if(i==0||j==0)
num[i][j]=1;将第一行或第一列并且两个字符相等赋值为1
else
{
num[i][j] = num[i-1][j-1]+1;不是第一行或第一列但相等的执行该语句
}
if(num[i][j]>max) 记录最大的数和s1此时的i值
{
max = num[i][j];
end = i;
}
}
}
}
if(max==0)
cout<<"-1"<<endl;
for(int i = end-max+1;i<=end;i++)打印最长公共子串
{
cout<<s1[i];
}
cout<<endl;
}
}