描述
给出两个整数n和k,(2≤n≤70000,1≤k≤n),求出1,2,3,…,n中连续k个数的和,并计算出和为平方数的个数。
例如n=10,k=3。在1,2,…,10中,连续3个数的和有
1+2+3=6
2+3+4=9
3+4+5=12
4+5+6=15
5+6+7=18
6+7+8=21
7+8+9=24
8+9+10=27
其中和为平方数的仅有9,因为9=3×3。
输入描述
n,k两个整数。
输出描述
一个整数,即1,2,…,n中连续k个数的和为平方数的个数。
用例输入 1
10 3
用例输出 1
1
来源
省赛
解析:
-
代码首先通过标准输入读取整数
n
和k
。 -
然后,代码初始化一个计数器
c
为0,用于记录连续k个数的和为平方数的个数。 -
接着,使用一个for循环从
k
遍历到n
。这是因为我们需要至少k
个数才能形成一个连续的k
个数的序列。 -
在循环内部,使用等差数列求和公式来计算从第
i
个数开始的连续k
个数的和。公式为:t = k * i - k * (k - 1) / 2
。 -
然后,代码检查
t
是否为平方数。这里使用的方法是计算t
的平方根,然后比较平方根的平方是否等于t
。但是,这种方法由于浮点数的精度问题可能会导致误判。一种更稳妥的方法是使用整数运算来检查平方数。 -
如果
t
是平方数,则计数器c
自增。 -
最后,代码输出计数器
c
的值,即连续k个数的和为平方数的个数。
#include<bits/stdc++.h> // 引入标准库,包含了几乎所有常用的头文件
using namespace std; // 使用标准命名空间
const int N = 70007; // 定义一个常量N,用于数组a的大小,通常为了保险起见,我们会将数组大小设为n的最大值加1
int n, k, c; // 定义三个整型变量,n表示序列长度,k表示连续数的个数,c用于计数和为平方数的个数
int a[N]; // 定义一个整型数组a,但在这个问题中数组a并没有实际使用到 int main() { cin >> n >> k; // 从标准输入读取n和k的值 c = 0; // 初始化计数变量c为0 for(int i = k; i <= n; i++) // 从k开始循环到n,因为至少需要k个数才能组成连续k个数的序列 { // 计算从第i个数开始的连续k个数的和 // 这里使用的是等差数列求和公式,首项为i-k+1,末项为i,项数为k int t = k * i - k * (k - 1) / 2; // 检查t是否为平方数 // 使用sqrt函数计算平方根,然后比较平方根的平方是否等于t // 注意:这种方法存在精度问题,因为sqrt返回的是浮点数,直接比较可能会有误差 if(int(sqrt(t)) == sqrt(t)) c++; // 如果t是平方数,则c自增 } cout << c << endl; // 输出计数结果c return 0; // 程序正常结束,返回0
}