一道有趣的编程题

Problem Description (HDU 6630)
You are given three positive integers N , x , y N, x, y N,x,y.
Please calculate how many permutations of 1~N satisfies the following conditions (We denote the i i i-th number of a permutation by p i p_i pi):

  1. p 1 = x p_1 = x p1=x
  2. p N = y p_N = y pN=y
  3. for all 1 ≤ i &lt; N 1 \leq i &lt; N 1i<N, ∣ p i − p i + 1 ∣ ≤ 2 |p_i-p_{i+1}| \leq 2 pipi+12

Input
The first line contains one integer T T T denoting the number of tests.
For each test, there is one line containing three integers N , x , y N, x, y N,x,y.

  • 1 ≤ T ≤ 5000 1\leq T \leq 5000 1T5000
  • 2 ≤ N ≤ 1 0 5 2 \leq N \leq 10^5 2N105
  • 1 ≤ x &lt; y ≤ N 1\leq x &lt; y \leq N 1x<yN

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

// HDU 6630
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const ll MOD = 998244353;
const int maxn = 1e5+5;
int N, x, y;
ll dp[maxn];
void cal(){
	// 从最左端蹦到最右端(按照题目要求),一共有多少种方法。
	// 记长度为k,每一点都要经历且仅经过一次,且不经过此k个点之外的剩下的点
	dp[1] = 1, dp[2] = 1, dp[3] = 1;
	for(int i = 4; i < maxn; i++)
		dp[i] = (dp[i-1]+dp[i-3])%MOD;
}
int main(){
	// freopen("in.txt", "r", stdin);
	// freopen("fun.out", "w", stdout);
	int T; scanf("%d", &T);
	cal();
	while(T--){
		scanf("%d%d%d", &N, &x, &y);
		if(x > y) swap(x, y);
		int left = x-1, right = N-y, mid = y-x-1;
		if(left != 0 && mid == 0 && right != 0) {
			printf("0\n");
			continue;
		}
		if(mid == 0){
			printf("1\n");
			continue;
		}
		if(left == 0 && right == 0){
			printf("%d\n", (int)dp[N]);
			continue;
		}
		if(left == 0){ // eg. 6 5 1
			printf("%d\n", (int)dp[y-1]);
			continue;
		}
		if(right == 0){
			y = N+1-x;
			printf("%d\n", (int)dp[y-1]);
			continue;
		}
		printf("%d\n", (int)dp[mid]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值