2019 Multi-University Training Contest 5——permutation 2
题意:
t组输入,之后每组例子有三个数n、x、y代表在一个以x为开头y为结尾的长为n的数组里面,开头和结尾数据已经固定,让你从1——n中找其他数据填入数组中
(每个数据不能重复使用),使它满足abs(v[i+1]-v[i])>=2(i<=n-1) ,问有多少中排序可以满足这个情况
题解:
先暴力打出一组数据
这是n=11的时候
i表示x,j表示y
1 i:1 j:2 sum:1 2 i:1 j:3 sum:1 3 i:1 j:4 sum:1 4 i:1 j:5 sum:2 5 i:1 j:6 sum:3 6 i:1 j:7 sum:4 7 i:1 j:8 sum:6 8 i:1 j:9 sum:9 9 i:1 j:10 sum:13 10 i:1 j:11 sum:28 11 12 i:2 j:3 sum:0 13 i:2 j:4 sum:1 14 i:2 j:5 sum:1 15 i:2 j:6 sum:1 16 i:2 j:7 sum:2 17 i:2 j:8 sum:3 18 i:2 j:9 sum:4 19 i:2 j:10 sum:6 20 i:2 j:11 sum:13 21 22 i:3 j:4 sum:0 23 i:3 j:5 sum:1 24 i:3 j:6 sum:1 25 i:3 j:7 sum:1 26 i:3 j:8 sum:2 27 i:3 j:9 sum:3 28 i:3 j:10 sum:4 29 i:3 j:11 sum:9 30 31 i:4 j:5 sum:0 32 i:4 j:6 sum:1 33 i:4 j:7 sum:1 34 i:4 j:8 sum:1 35 i:4 j:9 sum:2 36 i:4 j:10 sum:3 37 i:4 j:11 sum:6 38 39 i:5 j:6 sum:0 40 i:5 j:7 sum:1 41 i:5 j:8 sum:1 42 i:5 j:9 sum:1 43 i:5 j:10 sum:2 44 i:5 j:11 sum:4 45 46 i:6 j:7 sum:0 47 i:6 j:8 sum:1 48 i:6 j:9 sum:1 49 i:6 j:10 sum:1 50 i:6 j:11 sum:3 51 52 i:7 j:8 sum:0 53 i:7 j:9 sum:1 54 i:7 j:10 sum:1 55 i:7 j:11 sum:2 56 57 i:8 j:9 sum:0 58 i:8 j:10 sum:1 59 i:8 j:11 sum:1 60 61 i:9 j:10 sum:0 62 i:9 j:11 sum:1 63 64 i:10 j:11 sum:1
之后就是从中找规律(把它弄成一个表格更好找)
对于x==1这种的
先赋初值v[y==2]=1,v[y==3]=1,v[y==4]=1,v[y==1]=0
之后的规律就是v[i]=v[i-1]+v[i-3]
这种是x==1的,那么x!=1的时候
如果y不是n的时候答案在
v[y-x]
y==n的时候就是
v[y-x+1]
这就是规律(真难找T_T)
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 const int maxn=1e5+10; 8 const int mod = 998244353; 9 ll v[maxn]; 10 int main() 11 { 12 v[1]=0; 13 v[4]=v[2]=v[3]=1; 14 for(ll i=5;i<=1e5;++i) 15 { 16 v[i]=(v[i-1]+v[i-3])%mod; 17 } 18 ll t; 19 scanf("%lld",&t); 20 while(t--) 21 { 22 ll n,x,y; 23 scanf("%lld%lld%lld",&n,&x,&y); 24 if(x==1) 25 { 26 if(y==n) 27 printf("%lld\n",v[n+1]); 28 else printf("%lld\n",v[y]); 29 } 30 else 31 { 32 if(y==n) 33 printf("%lld\n",v[y-x+1]); 34 else printf("%lld\n",v[y-x]); 35 } 36 } 37 return 0; 38 }