题目
解题思路
常规方法是可以根据人数还有栋栋喊出的数设置一个双循环,进行求解但是该方法遇到数字比较大时会超时。
代码是
n,k,T=input().strip().split()
sum=0
index=1
time=1
for i in range(int(T)):
for j in range(int(n)):
if j==0:
sum+=index
index+=time
time+=1
if index>int(k):
index=index%int(k)
print(sum)
为了不打破时间限制,我们则采用另一种方法,由于每次递增是+1,+2,+3,+4我们可以把这个递增的数列看成一个递增数列1,2,3,4。
因此:
1.同学们喊的数本质上是一个等差数列的和,因为 j 固定的增长量为1
2.假设 f(n) 为第n个同学喊的数,暂不考虑k的情况下,则 f(1) - f(10) 如下表所示:
3. 根据等差数列的前n项和公式S(n)=a1*n+n*(n-1)/2*d,可以得出f(n)=n*(n-1)/2+1;
4.为了不和题目中的n混淆,我们将第x个同学喊的数f(x)=x*(x-1)/2+1,考虑k的规则后f(x)=(x*(x-1)/2+1)%k;
5.但我们并不需要把所有同学喊的数都加起来,我们只需要将栋栋自己喊的数加起来就可以了,假设有n=3,也就是一共只有3个同学,我们需要加上的数如下表黄色的数据部分所示:
6.根据上表能看出我们需要加的项为 f(n*i+1),n为同学数量,i=0,1,2, ...... t,t为题目中栋栋说出的数字的个数
7.再结合上面 f(x) 的公式,将x=n*i+1,那结果就出来了,f(i)=((n*i+1)*((n*i+1)-1)/2+1)%k,简化一下可得 f(i)=(n*i*(n*i+1)/2+1)%k,写成代码如下:
代码为:
n,k,T = map(int, input().split())
ans = 0
for i in range(T):
ans+=(1 + n * i * (n * i + 1)// 2)%k
print(ans)