目录
1.阶乘问题,我会的第一的递归题,经典
链接:https://ac.nowcoder.com/acm/problem/14840
来源:牛客网题目描述
输入一个非负整数,求其阶乘。
输入描述:输入一个非负整数n.
输出描述:
输出非负整数n的阶乘
示例1
输入
复制4
输出
复制24
备注:
1.数据大小均在 long long 范围内。(python无视此条备注)
2.0! = 1
#include <iostream>
using namespace std;
long long int fun(int n){
if(n==1)
return 1;
return n*fun(n-1);
}
int main(){
long long int n;
cin>>n;
long long int num;
if(n==0){
cout<<1<<endl;
}else{
num=fun(n);
cout<<num<<endl;
}
return 0;
}
2.小q的数列
链接:https://ac.nowcoder.com/acm/problem/15979
来源:牛客网题目描述
小q最近迷上了各种好玩的数列,这天,他发现了一个有趣的数列,其递推公式如下:f[0]=0 f[1]=1;
f[i]=f[i/2]+f[i%2];(i>=2)现在,他想考考你,问:给你一个n,代表数列的第n项,你能不能马上说出f[n]的值是多少,以及f[n]所代表的值第一次出现在数列的哪一项中?(这里的意思是:可以发现这个数列里某几项的值是可能相等的,则存在这样一个关系f[n'] = f[n] = f[x/2]+f[x%2] = f[x]...(n'<n<x) 他们的值都相等,这里需要你输出最小的那个n'的值)(n<10^18)
输入描述:输入第一行一个t
随后t行,每行一个数n,代表你需要求数列的第n项,和相应的n'
(t<4*10^5)输出描述:
输出每行两个正整数
f[n]和n',以空格分隔示例1
输入
复制2
0
1输出
复制0 0
1 1
先将前MAX个数列计算出来,在对每个输入的进行对比得出结果,这样写自己测试没有问题,但在OJ上会出现段错误……
#include <iostream>
using namespace std;
typedef long long ll;
const ll MAX=100;
int main(){
ll t;
cin>>t;
ll n[t];
for(ll i=0;i<t;i++){
cin>>n[i];
}
ll f[MAX];
f[0]=0;
f[1]=1;
for(ll i=2;i<MAX;i++){
f[i]=f[i/2]+f[i%2];
cout<<"f"<<"["<<i<<"]"<<"="<<f[i]<<endl;
}
for(ll j=0;j<t;j++){
cout<<f[n[j]]<<" ";
if(n[j]==0){
cout<<0<<endl;
}else if(f[n[j]]!=f[n[j]-1]){
cout<<n[j]<<endl;
}else{
int k=n[j];
while(f[k--]==f[n[j]]){
}
cout<<k+2<<endl;
}
}
return 0;
}
后改成递归,自己测也是没有毛病,但在OJ上超内存了??
#include <iostream>
using namespace std;
typedef long long ll;
ll fun(int n){
if(n==0){
return 0;
}else if(n==1){
return 1;
}
return fun(n/2)+fun(n%2);
}
int main(){
ll t;
cin>>t;
ll n[t];
for(ll i=0;i<t;i++){
cin>>n[i];
ll num=fun(n[i]);
cout<<num<<" ";
if(n[i]==0){
cout<<0<<endl;
}else{
for(ll j=n[i];j>=0;j--){
if(fun(j)!=fun(n[i])){
cout<<j+1<<endl;
break;
}
}
}
}
return 0;
}
这题OJ上就一个测试点,估计是大数,难搞
第二个输出是由规律的,得找到数的规律,具体是sum=sum*2+1,gg这题我笑了
用递归会超时,找到位运算的规律可以AC,那为啥放在递归专栏里……wtcl
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
long long int T,num,n;
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);
num = 0;
while(n)
{
if(n&1)
num++;
n >>=1;
}long long int sum=0;
for(long long int i=0;i<num;i++)
sum=sum*2+1;
printf("%lld %lld\n",num,sum);
}
return 0;
}
3.递归公式题(1)
递归过深栈溢出,明显是一个DP问题,牛客纯递归问题已经不多啦
链接:https://ac.nowcoder.com/acm/problem/20660
来源:牛客网题目描述
令f(n)=2*f(n-1)+3*f(n-2)+n,f(1)=1,f[2]=2。
告诉你n,输出f(n)的结果,结果对1e9+7取模。
输入描述:多组输入,每行一个整数n(1<=n<=1000),如果输入为0,停止程序。
输出描述:
输出对应g(n)的值,结果对1e9+7取模。
示例1
输入
复制1
5
9
456
0输出
复制1
95
7789
734891569备注:
取模即求余运算,如7%4=3,12%5=2。
#include <iostream>
using namespace std;
unsigned int d=1e9+7;
unsigned int f(int n){
static unsigned int i[1001];
if(n==1||n==2)
return n;
if(i[n])
return i[n];
i[n] = (2*f(n-1)%d+3*f(n-2)%d+n)%d;
return i[n];
}
int main(){
unsigned int t;
while(true){
cin>>t;
if(t==0){
break;
}
unsigned int num=f(t);
cout<<(num%d)<<endl;
}
return 0;
}