2019杭电多校permutation 2 (6630) 斐波那契数列

2019杭电多校permutation 2 (6630) 斐波那契数列

题目:http://acm.hdu.edu.cn/showproblem.php?pid=6630

题意:

给你n,x,y三个数字,表示数组大小为n,p[1] = x,p[n] = y.然后规定p[i]和p[i-1]之间数值之差不超过2,求一共有多少种排列方式。

题解:

emmmmm,其实我是暴力写出所以答案然后再找出规律的…
在这里插入图片描述
我们可以很快发现输入n 1 n这样得出来的答案都是符合斐波那契数列的(具体为啥我也不知道)
我们就能够发现这个斐波那契公式f[i] = f[i-1] + f[i-3]
写出前10项:
0 1 1 1 2 3 4 6 9 13 19
那我们再换其他的输入试试。
在这里插入图片描述
很快我们也能发现输入n x n我们得到的答案也符合斐波那契数列,并且这个答案和前面的输入n 1 n答案只差x位,所以我们可以推出答案应该在斐波那契数列的第n-x项
那我们再试试输入其他的
在这里插入图片描述
我们发现输入n 1 y也符合斐波那契数,并且答案与n无关,只和y相关。经过观察+猜想我们就能呢个得出这个答案是斐波那契数列的第y-1项
最后再试一下输入n x y
在这里插入图片描述
我们通过观察能发现这个答案与n无关,与y-x相关。对比之前的斐波那契数列我们可以得出答案应该是斐波那契的第y-x-1项

AC代码

#include<stdio.h>
#define ll long long
#define maxn 100005
#define mod 998244353
ll f[maxn];
void fib(ll n)
{
	f[0] = 0,f[1] = 1,f[2] = 1, f[3] = 1;
	for(ll i = 4;i<=n;i++)
	{
		f[i] = f[i-1]%mod + f[i-3]%mod;
		f[i] %= mod;
	}
		
}
int main()
{
	fib(maxn);
	int T,n,x,y;
	scanf("%d",&T);
	int p;
	while(T--)
	{
		scanf("%d %d %d",&n,&x,&y);
		if(x==1&&y==n) p = n;
		else if(y == n) p = n-x;
		else if(x == 1) p = y-1;
		else p = y-x-1;
		printf("%lld\n",f[p]);
	}
}

暴力的代码(可以用来测试)

#include<stdio.h>
#include<string.h>
#define ll long long
#define maxn 100005
int mark[maxn],ans[maxn];
int step = 0;
void dfs(int n,int x,int y,int index)
{
	for(int i=-2;i<=2;i++)
	{
		if(x+i <= n && x+i >= 1 && mark[x+i] == 0)
		{
			mark[x+i] = 1;
			ans[index] = x+i;
			if(index == n-2 && y<=x+i+2 && y>= x+i-2)
			{
				for(int j=0;j<n;j++)
					printf("%d ",ans[j]);
				puts("");
				mark[x+i] = 0;
				ans[index] = 0;
				step++;
				return;
			}
			else if(index != n-2)
			{
				dfs(n,x+i,y,index+1);
				mark[x+i] = 0;
				ans[index] = 0;
			}
			else
			{
				mark[x+i] = 0;
				ans[index] = 0;
				return ;
			}
		}
		else if(i == 2)
		{
			mark[x] = 0;
			ans[index] = 0;
			return ;
		}
	}
	if(index == 1)
		return;
}
int main()
{
	int T,n,x,y;
	//scanf("%d",&T);
	T = 100;
	int p;
	while(T--)
	{
		scanf("%d %d %d",&n,&x,&y);
		if(x>y)
		{
			x ^= y ^= x ^= y;
		}
		memset(mark,0,sizeof(mark));
		memset(mark,0,sizeof(ans));
		mark[x] = 1;
		mark[y] = 1;
		ans[0] = x;
		ans[n-1] = y;
		dfs(n,x,y,1);
		printf("step = %d\n",step);
//		if(x==1&&y==n) p = n;
//		else if(y == n) p = n-x;
//		else if(x == 1) p = y-1;
//		else p = y-x-1;
//			printf("p = %d\n",p);
		step = 0;
	}
}
发布了51 篇原创文章 · 获赞 16 · 访问量 3367

猜你喜欢

转载自blog.csdn.net/weixin_43911945/article/details/98624070