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;
}
}