-
2 15 8
样例输出
-
5 1
描述
每一个正整数 N 都能表示成若干个连续正整数的和,例如10可以表示成1+2+3+4,15可以表示成4+5+6,8可以表示成8本身。我们称这种表示方法为SCI(Sum of Consecutive Integers)表示法。
小Hi发现一个整数可能有很多种SCI表示,例如15可以表示成1+2+3+4+5,4+5+6,7+8以及15本身。小Hi想知道N的所有SCI表示中,最多能包含多少个连续正整数。例如1+2+3+4+5是15包含正整数最多的表示。
输入
第一行一个整数 T,代表测试数据的组数。
以下 T 行每行一个正整数N。
对于30%的数据,1 ≤ N ≤ 1000
对于80%的数据,1 ≤ N ≤ 100000
对于100%的数据,1 ≤ T ≤ 10,1 ≤ N ≤ 1000000000
输出
对于每组数据输出N的SCI表示最多能包含多少个整数。
思路:
简单枚举,假设连续正整数的首项是a,项数是m,那么根据等差数列求和公式有:
n
=
(
a
+
a
+
m
−
1
)
∗
m
2
n = \frac{(a+a+m-1)*m}{2}
n=2(a+a+m−1)∗m
于是有:
2
∗
n
=
(
2
∗
a
+
m
−
1
)
∗
m
2*n = (2*a+m-1)*m
2∗n=(2∗a+m−1)∗m
所以 m 是 2n的约数。我们可以枚举2n所有的约数,并检查a是否有整数解。然后记录m的最大值就是答案。由于约数是成对出现的,所以只要枚举
[
1
,
2
∗
n
]
[1,\sqrt{2*n}]
[1,2∗n]就行。
#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
void solve(int& n) {
int sum = 2*n;
int res = 0;
int nums = sqrt(sum);
for (int i = 1; i <= nums; ++i) {
if (sum%i == 0) {
int tmp = (sum/i + 1 - i) / 2;
if((tmp*2+i-1)*i == sum)
res = max(res,i);
}
}
cout << res << endl;
}
int main()
{
/* code */
int t, n;
cin >> t;
while(t--) {
cin >> n;
solve(n);
}
return 0;
}