http://acm.hdu.edu.cn/showproblem.php?pid=6630
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 354 Accepted Submission(s): 192
Problem Description
You are given three positive integers N,x,y.
Please calculate how many permutations of 1∼N satisfies the following conditions (We denote the i-th number of a permutation by pi):
1. p1=x
2. pN=y
3. for all 1≤i
Input
The first line contains one integer T denoting the number of tests.
For each test, there is one line containing three integers N,x,y.
* 1≤T≤5000
* 2≤N≤105
* 1≤x
Output
For each test, output one integer in a single line indicating the answer modulo 998244353.
Sample Input
3
4 1 4
4 2 4
100000 514 51144
Sample Output
2 1 253604680
WA的代码(dfs暴力,仅用来产生数据来推理下面的公式):
#include
#include
#include
#include
using namespace std;
int ans[500000];
int cnt;
bool vis[500000];
int N,x,y;
void dfs(int num,int pos,int step) {
if(vis[num]) return;
if(pos >= N) return;
if(pos == N-1){
if(abs(num-y) > 2){
return;
}
}
ans[pos] = num;
vis[num] = true;
step++;
if(step == N-2) {
cnt++;
vis[num] = false;
step--;
for(int i = 1;i <= N;i++){
cout << ans[i] << " ";
}
cout << endl;
return;
}
for(int k = num-2;k <= num+2;k++){
if(k == num || k < 1 || k > N || k == y || vis[k]) continue;
dfs(k,pos+1,step);
}
step--;
vis[num] = false;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
memset(vis,false,sizeof(vis));
memset(ans,0,sizeof(ans));
cnt = 0;
scanf("%d%d%d",&N,&x,&y);
ans[1] = x;
ans[N] = y;
vis[x] = vis[y] = true;
int step = 0;
for(int j = x-2;j <= x+2;j++){
if(j == x || j < 1 || j > N || j == y || vis[j]) continue;
dfs(j,2,step); //num ans`s pos
}
printf("%d\n",cnt % 998244353);
}
}
斐波那契数列
1 1 1 2 3 4 6 9 13 19 28 ...........
然后对照下面核心代码那里就知道为什么跟斐波那契数列有关了
AC代码如下:
#include
#include
#include
using namespace std;
#define ll long long
const ll maxn = 1e6 + 10;
const ll MOD = 998244353;
int a[maxn];
void init(){
for(int i = 3;i < maxn;i++){
a[i] = a[i-1] + a[i-3];
if(a[i] >= MOD){
a[i] -= MOD;
}
}
}
int main(){
int T;
cin >> T;
a[0] = 0;
a[1] = a[2] = 1;
init();
while(T--){
int N,x,y,l,r;
scanf("%d%d%d",&N,&x,&y);
if(x == 1){
l = 1;
}else{
l = x+1;
}
if(y == N){
r = N;
}else{
r = y-1;
} // 然后求 [l,r]数字的全排列的种数
//然而该种数竟然跟 斐波那契数列有关; 公式如右: f(i) = f(i-1) + f(i-3) 0 1 1 1 2 3 // 4 6 .......
if(x != 1 && y != N){ //核心代码
printf("%d\n",a[y-x-1]);
}else if(x == 1 && y == N){
printf("%d\n",a[y]);
}else if(x == 1 && y != N){
printf("%d\n",a[y-1]);
}else if(x != 1 && y == N){
printf("%d\n",a[y-x]);
} //核心代码
}
return 0;
}