【每日一题】—— B. Fibonaccharsis (Codeforces Round 887 (Div. 2))

博客主页:PH_modest的博客主页
当前专栏:每日一题
其他专栏:
每日反刍
C++跬步积累
C语言跬步积累
座右铭:广积粮,缓称王!

一.题目描述

【每日一题】—— B. Fibonaccharsis (Codeforces Round 887 (Div. 2))_第1张图片

题目大意

告诉你第k项是n,问你1~k项能不能组成一个类斐波那契数列,如果能输出一个有几种情况,如果没有就输出0。

题目链接

B. Fibonaccharsis (Codeforces Round 887 (Div. 2))

二.思路分析

  1. 首先设第一个数为a,第二个数为b,根据斐波那契数列的性质可以往后推导出如下的数列:
    【每日一题】—— B. Fibonaccharsis (Codeforces Round 887 (Div. 2))_第2张图片
  2. 我们再写出以0,1为开头的类菲波拉契数列(下面简称Fib):
    【每日一题】—— B. Fibonaccharsis (Codeforces Round 887 (Div. 2))_第3张图片
  3. 两者相互比较一下不难得出a,b前的系数和它对应下标的关系:a的系数就是:Fib(i-1)b的系数就是:Fib(i)
  4. 那么该题就变成了已知第i项的值,让我们根据aX+bY=n(a为X的系数,b为Y的系数,该式中的X、Y就是第三点中说的a、b,n是题目告诉我们的值)求满足条件的X、Y有几个
  5. 代码思路就是枚举X,求是否有整数Y且Y大于等于X

注意点:斐波那契数列最多到第30项,不然会炸,所有需要提前特判一下,如果大于第30项就输出0。
比赛的时候没注意到这个,直接被hack了,错失上大分的好机会,我哭死

三.代码展示

友情提醒:我代码中定义的变量具体的功能作用和题目中不一定是一一对应的,比如我代码中的n表示第n项,k表示第n项上的数字……

//找规律
//第n个数可以用Fib(n-1)*x+Fib(n)*y来表示,Fib是以0,1为开头的斐波那契数列,x是所求菲波拉契数列的第一个元素,y是第二个元素,x从0开始遍历,找是否有符合的x使得y是整数且大于等于x
//菲波拉契数最多30次,不然会爆
#include
#include
#include
#include
using namespace std;

int Fib(int n)//找系数,迭代法
{
	int a = 0;
	int b = 1;
	int c = 0;
	if (n == 1)
	{
		return 0;
	}
	else if (n == 2)
	{
		return 1;
	}
	else if (n > 2)
	{
		while (n > 2)
		{
			c = a + b;
			a = b;
			b = c;
			n--;
		}
		return c;
	}
}

void solve()
{
	int sum=0;
	int k,n;//k表示第k项,n表示第k项上的数字
	cin>>k>>n;
	int x,y;//x表示第一项,y表示第二项
	int a,b;//a是x的系数,b是y的系数
	if(n>30)//这边需要特判一下,大于30直接输出0
	{
		cout<<0<<"\n";
		return;
	}
	a=Fib(n-1);
	b=Fib(n);
	for(x=0;x<=k/2;x++)
	{
		if((k-(a*x))%b==0&&(k-(a*x))/b>=x)//y应该是整数且大于等于x
		{
			sum++;
		}
	}
	cout<<sum<<endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
	return 0;
}

最后:

每日一题系列旨在养成刷题的习惯,所以对代码的解释并不会特别详细,但足够引导大家写出来,选的题目都不会特别难,但也不是特别简单,比较考验大家的基础和应用能力,我希望能够将这个系列一直写下去,也希望大家能够和我一起坚持每天写代码。

之后每个星期都会不定期更新codeforces和atcoder上的题目,想要学习算法的友友们千万别错过了,欢迎评论区讨论!!!

在这里送大家一句话:广积粮,缓称王!

你可能感兴趣的:(每日一题,算法,学习,c++,codeforces)