这道题可以从多个样例推出规律
先附上学长dfs暴力枚举所有情况的代码(太大会T)
const int maxn = 1e5 + 10;
int num[maxn], used[maxn];
int n, x, y;
ll ans;
vector<int> tmp;
void dfs(int x, int cnt) {
if(cnt == n-1) {
if(abs(tmp[tmp.size() - 1] - y) <= 2) {
ans++;
for(int i = 0; i < tmp.size(); i++) {
cout << tmp[i] << " ";
}
cout << y << endl;
}
return;
}
for(int i = max(1, x - 2); i <= min(x + 2, n); i++) {
if(!used[i] && abs(tmp[tmp.size() - 1] - i) <= 2) {
used[i] = 1;
tmp.push_back(i);
dfs(i, cnt + 1);
// if(ans >= 20) {
// return ;
// }
used[i] = 0;
tmp.erase(--tmp.end());
}
}
}
从样例可以看出
起点左面一部分固定,终点固定,只有中间在变化可构成斐波那契
可以先将一个数组确定为答案数列,输入n,x,y可直接求出答案
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll Max = 1e6+5;
const ll Mod = 998244353;
ll ans[Max];
int main(){
ans[1] = ans[2] = ans[3] = 1;
for(int i = 4;i < Max;i++){
ans[i] = (ans[i-1] + ans[i-3]) % Mod;
}//上面都为确定答案数组
ll T,N,x,y;
while(~scanf("%lld",&T)){
while(T--){
scanf("%lld%lld%lld",&N,&x,&y);
if(x != 1)
x++;
if(y != N){
y--;
}
printf("%lld\n",ans[y-x+1]);
}
}
}