题目解析
* 输入输出:第一行输入整数 nnn 表示序列长度,第二行输入 nnn 个非负整数。输出一个整数,表示满足 1≤i<j≤n1 \le i < j \le n1≤i<j≤n 且 Ai+AjA_i + A_jAi +Aj 为完全平方数的无序对 (i,j)(i,j)(i,j) 的数量。
* 数据范围:1≤n≤10001 \le n \le 10001≤n≤1000,0≤Ai≤1050 \le A_i \le 10^50≤Ai ≤105。两数之和最大为 2×1052 \times 10^52×105,在 32 位整数范围内。
* 复杂度要求:n≤1000n \le 1000n≤1000,双重循环最多约 5×1055 \times 10^55×105 次迭代,时间复杂度 O(n2)O(n^2)O(n2) 符合 1s 限制;空间复杂度 O(n)O(n)O(n) 用于存储数组。
* 算法知识点:暴力枚举、双重循环、完全平方数判定
思路解析
1. 枚举无序对:使用双重循环遍历所有满足 i<ji < ji<j 的下标组合。外层循环 iii 从 111 到 nnn,内层循环 jjj 从 i+1i+1i+1 到 nnn,确保每对只被统计一次且不重复。
2. 判定完全平方数:对于每对元素之和 sum=Ai+Ajsum = A_i + A_jsum=Ai +Aj ,计算其整数平方根 sq=sumsq = \sqrt{sum}sq=sum 。由于浮点数精度问题,不直接判断 sqsqsq 是否为整数,而是通过验证 sq×sqsq \times sqsq×sq 是否等于 sumsumsum 来确认。若相等,则 sumsumsum 是完全平方数,答案计数器加一。
3. 精度处理:使用 int sq = sqrt(sum) 截断取整后,通过乘法回验可避免因浮点精度导致的误判(如 25\sqrt{25}25 可能存储为 4.99999994.99999994.9999999 或 5.00000015.00000015.0000001)。
完整代码