CF1718D. Many Perfect Squares 题解 枚举
题目链接:https://codeforces.com/problemset/problem/1781/D
题目大意
给你一个长度为 的数列 。
你需要在 范围内找到一个整数 ,并将数列 中每个元素的数值都加上 得到一个新的数列 。
你希望使新的数列中平方数的个数尽可能地多。
求:你能够得到的新数列中最多的平方数的个数。
题解
首先答案至少是 。
接着我们考虑能否得到至少 个数? 我们可以枚举 和 (),并找出 的哪些值 和 都是完全平方数。
我们可以写出两个等式: 和 ,对于某个非负整数 。
我们将第一个等式减去第二个等式,并应用两个平方差的公式: 。可知, 是 的正的因数。
我们可以以 的时间复杂度枚举 的所有因数。
对于每个这样的因数 ,我们都可以得到一个简单的方程组,即 和 的方程组,如下:
如果 和 都是整数,那就意味着我们找到了 的候选值: .
对于 的每个候选值,我们只需计算它的平方和并找出最大值即可。
示例程序:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int T, n, a[55];
// 判断整数 a 是不是平方数
bool check(int a) {
int b = sqrt(a);
return b * b == a;
}
int cal() {
int res = 1; // 至少能得到一个平方数
for (int i = 1; i < n; i++) {
for (int j = i+1; j <= n; j++) {
int num = a[j] - a[i];
for (int d = 1; d * d <= num; d++) {
if (num % d || num / d % 2 != d % 2)
continue;
int p = (num / d - d) / 2;
int q = (num / d + d) / 2;
assert(p * p - a[i] == q * q - a[j]);
int x = p * p - a[i];
if (x < 0) // x 在 [0, 1e18] 范围内
continue;
int cnt = 0;
for (int k = 1; k <= n; k++)
if (check(a[k] + x))
cnt++;
// cout << "x = " << x << ", cnt = " << cnt << endl;
res = max(res, cnt);
}
}
}
return res;
}
signed main() {
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
cout << cal() << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2020-10-14 洛谷P1967 货车运输 题解 最大生成树+LCA