##题目描述
栋栋正在和同学们玩一个数字游戏。
游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数字1。接下来,坐在栋栋左手边的同学要说下一个数字2。再下面的一个同学要从上一个同学说的数字往下数两个数说出来,也就是说4。下一个同学要往下数三个数,说7。依次类推。
为了使数字不至于太大,栋栋和同学们约定,当在心中数到 k-1 时,下一个数字从0开始数。例如,当k=13时,栋栋和同学们报出的前几个数依次为:
1, 2, 4, 7, 11, 3, 9, 3, 11, 7。
游戏进行了一会儿,栋栋想知道,到目前为止,他所有说出的数字的总和是多少。
样例说明
栋栋说出的数依次为1, 7, 9,和为17。
##输入格式
输入的第一行包含三个整数 n,k,T,其中 n 和 k 的意义如上面所述,T 表示到目前为止栋栋一共说出的数字个数。
数据规模和约定
1 < n,k,T < 1,000,000;
##输出格式
输出一行,包含一个整数,表示栋栋说出所有数的和。
##样例输入
3 13 3
##样例输出
17
解题思路
由题意可知,这个题目的实质是等差数列的求和,且d=1;在不考虑k的情况下,假设f(n)为每位同学喊得数字,如下图所示。
f(n) | |
1 | 1+0 |
2 | 1+0+1 |
4 | 1+0+1+2 |
7 | 1+0+1+2+3 |
11 | 1+0+1+2+3+4 |
16 | 1+0+1+2+3+4+5 |
22 | 1+0+1+2+3+4+5+6 |
29 | 1+0+1+2+3+4+5+6+7 |
37 | 1+0+1+2+3+4+5+6+7+8 |
46 | 1+0+1+2+3+4+5+6+7+8+9 |
已知等差数列的求和公式为S=a1*n+n*(n-1)*d/2,可得f(n)=n*(n-1)/2+1;然后考虑题目中k的问题可得f(n)=(n*(n-1)/2+1)%k。
然后是东东喊得数是如何得出的,当n=3 k=13 T=3时如下图中红色的数字为东东行出的数字。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
1 | 2 | 4 | 7 | 11 | 3 | 9 | 3 | 11 | 7 |
假设东东喊出的数字用t来表示:
t1=1;
t2=((1+2+3)+1)%13=((1+2+3)+t1)%k=7;
t3=((4+5+6)+7)%13=((4+5+6)+t2)%k=9;
1+2+3和4+5+6分别可以看作为首相分别为1,4末项分别为3,6的等差数列求和,则可得t=(((a+a+(n-1))*n/2+t)%k。
参考代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long sum=1,a=1,t=1;//t表示东东每次说的数
int n,k,T;//T表示目前为止一共说出的数字个数
cin>>n>>k>>T;
for(int i=1;i<T;i++)
{
t=(((a+a+(n-1))*n/2)+t)%k;
sum+=t;
a+=n;
}
cout<<sum<<endl;
return 0;
}