递归——牛客二星OJ整理

目录

1.阶乘问题,我会的第一的递归题,经典

2.小q的数列

3.递归公式题(1)


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;
} 
发布了228 篇原创文章 · 获赞 76 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_41895747/article/details/103887733