牛客训练赛62 B题病毒扩散
链接:https://ac.nowcoder.com/acm/contest/5205/B
来源:牛客网
题目描述
牛牛所在的城市有一种新型病毒开始扩散。在一个二维平面坐标系上,有一个感染者在 (0,0) 的位置。从 时刻 0 开始,每一个在 (x,y) 的感染者都会让下一个时刻 (x+1,y),(x,y+1) 的感染者数量增加 1。
链接:https://ac.nowcoder.com/acm/contest/5205/B
来源:牛客网
上图展示了时刻 0 和时刻 1 病毒的扩散情况。在时刻 1,(0,0),(0,1),(1,0) 的感染者数量为 1。在时刻 2,(0,0),(0,2),(2,0) 的感染者数量为 1, (0,1),(1,0),(1,1) 的感染者数量为 2。
牛牛想知道,对于特殊的 n 个点,在时刻 t 感染者的数量。
输入描述:
第一行一个正整数n,表示特殊点的数量。
接下来 n 行,每行三个非负整数 xi,yi,ti,表示有一个特殊的点在 (xi,yi),牛牛想知道在时刻 ti,这个点有多少感染者。
输出描述:
对于每一个特殊的点,输出一行一个非负整数,表示在 t 时刻这个点的感染者数量,对 998244353 取模。
示例1
输入
3
0 0 1
1 1 2
2 0 2
输出
1
2
1
示例2
输入
5
5 5 7
2 7 9
0 14 14
0 14 15
14 29 100
输出
0
36
1
15
891148910
思路:首先画图分析前几秒内的每个格子的感染人数分布
这里只列举到t=4的情况。
由列举出来的图表可以很轻易的发现规律
围城边界的数列是 (x+1)^t 的展开式的系数。
当t=0时,各项系数为1
当t=1时,各项系数为1,1
当t=2时,各项系数为1,2,1
当t=3时,各项系数为1,3,3,1
当t=4时,各项系数为1,4,6,4,1
当t=5时,各项系数为1,5,10,10,5,1
每一时间的非0部分所围成的三角形的边界都是由这个系数所组成的
除此之外,我们可以发现斜着的直线上的数列,也是跟这个系数成比例的
这些斜线的方程为 x+y=c(c为常数)
当 t=5 时
斜线上的数字:
x+y=0时,斜线上只有一个数字1
x+y=1时,斜线上的数字有5,5 与1,1成比例
x+y=2时,斜线上的数字有10,20,10 与1,2,1成比例
并且可以发现,比例为当前 t 所对应的这个系数
所以我们创建一个二维数组a[][]
a[i][j]表示,当t=i时,上述的系数的第j个数字
例如: a[5][3] 表示 t=5 时的系数表的第3个数字
t=5 时系数表为 1,5,10,10,5,1
下标从0开始,所以a[5][3]=10
将这么一个二维表建立后,剩下的就可以通过这个表中的数据O(1)的求出答案。
这个表也很容易找到规律
a [ i ] [ j ] = a [ i-1 ] [ j ] + a [ i-1 ] [ j-1 ];
然后可以通过判断
给出的点是否位于边界,分类的计算答案
当给出的点不在边界时,
ans = a [ x+y ] [ x ] * a [ t ] [ x+y ]
例如 x=2,y=1,t=5 时
(2,1)这个点位于x+y=3上他的值应该是t=3时的系数(1,3,3,1)中的第2(x)(其实这里选x和y都一样=。=!)个乘上10(t=5时的第(2+1)(x+y)个系数)
由此总结出公式:
ans = a [ x+y ] [ x ] * a [ t ] [ x+y ];
ac代码如下
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long a[5005][5005];
int main(){
a[0][0]=1;
for (int i=1;i<=5000;i++){//建表
for (int j=i;j>=0;j--){
a[i][j]=(a[i-1][j-1]+a[i-1][j])%mod;
}
}
int n,x,y,t;
scanf("%d",&n);
while(n--){
scanf("%d %d %d",&x,&y,&t);
if ((x+y)>t){//当给出的点在目前已经建成的三角形外时
printf("0\n");
continue;
}
if (x==0){//处于边界
printf("%d\n",a[t][y]);
}
else if (y==0){//处于边界
printf("%d\n",a[t][x]);
}
else if (x+y==t){//处于边界
printf("%d\n",a[t][x]);
}
else {//位于三角形内部
printf("%d\n",(a[x+y][x]*a[t][x+y])%mod);//
}
}
}