跳到主要内容

CF刷题遇到的一些数学题

Many Perfect Squares

题面翻译

nn 个数 (1n50)(1 \le n \le 50) 。 它们分别是 a1,a2,...,ana_1,a_2,...,a_n 。你需要选择一个数 xx ,使得 xx00101810^{18} 之内,并且 a1+x,a2+x,a3+x...an+xa_1 + x,a_2 + x,a_3 + x ... a_n +x 中有尽可能多的完全平方数。询问当 xx 最优时,有多少个数是完全平方数。

题目描述

You are given a set a1,a2,,ana_1, a_2, \ldots, a_n of distinct positive integers.

We define the squareness of an integer xx as the number of perfect squares among the numbers a1+x,a2+x,,an+xa_1 + x, a_2 + x, \ldots, a_n + x .

Find the maximum squareness among all integers xx between 00 and 101810^{18} , inclusive.

Perfect squares are integers of the form t2t^2 , where tt is a non-negative integer. The smallest perfect squares are 0,1,4,9,16,0, 1, 4, 9, 16, \ldots .

输入格式

Each test contains multiple test cases. The first line contains the number of test cases tt ( 1t501 \le t \le 50 ). The description of the test cases follows.

The first line of each test case contains a single integer nn ( 1n501 \le n \le 50 ) — the size of the set.

The second line contains nn distinct integers a1,a2,,ana_1, a_2, \ldots, a_n in increasing order ( 1a1<a2<<an1091 \le a_1 < a_2 < \ldots < a_n \le 10^9 ) — the set itself.

It is guaranteed that the sum of nn over all test cases does not exceed 5050 .

输出格式

For each test case, print a single integer — the largest possible number of perfect squares among a1+x,a2+x,,an+xa_1 + x, a_2 + x, \ldots, a_n + x , for some 0x10180 \le x \le 10^{18} .

样例输入 #1

4
5
1 2 3 4 5
5
1 6 13 22 97
1
100
5
2 5 10 17 26

样例输出 #1

2
5
1
2

In the first test case, for x=0x = 0 the set contains two perfect squares: 11 and 44 . It is impossible to obtain more than two perfect squares.

In the second test case, for x=3x = 3 the set looks like 4,9,16,25,1004, 9, 16, 25, 100 , that is, all its elements are perfect squares.

思路

注意到n其实很小,答案至少为1,因为可以使得任意一个数变成平方数

现在我们考虑加一个xx,可以使得至少两个数变为平方数到情况:

a[i]+x=p2a[i]+x=p^2

a[j]+x=q2a[j]+x=q^2

两式相减得到:a[i]a[j]=p2q2a[i]-a[j]=p^2-q^2

于是:a[i]a[j]=(p+q)(pq)a[i]-a[j]=(p+q)(p-q),这里(p+q)(pq)(p+q)和(p-q)显然是具有相同奇偶性的

因为nn很小,所以我们可以考虑枚举a[i]a[j]a[i]-a[j],即n2n^2,设diff=a[i]a[j]diff=a[i]-a[j],可以先对aa数组进行排序,降序排列

然后去枚举diffdiff的因子t=(pq)t=(p-q),得到如下结果:

pq=tp-q=t

p+q=difftp+q=\frac{diff}{t}

解方程得到p=(t+difft)2p=\frac{(t+\frac{diff}{t})}{2},因此x=p2a[i]x=p^2-a[i]

得到xx后,再去判断数组aa中的每个数是否都为平方数。

代码

#include <bits/stdc++.h>

#define int long long
#define yes cout << "YES" << endl;
#define no cout << "NO" << endl;
#define IOS cin.tie(0), cout.tie(0), ios::sync_with_stdio(false);
#define cxk 0
#define debug(s, x) if (cxk) cout << "#debug:(" << s << ")=" << x << endl;
using namespace std;

bool check(int x) {
int t = sqrt(x);
return t * t == x;
}

void solve() {
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a.begin() + 1, a.end());
reverse(a.begin() + 1, a.end());
int res = 1;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
int diff = a[i] - a[j];
for (int t = 1; t * t <= diff; t++) {
if (diff % t != 0) continue;
if (t % 2 != (diff / t) % 2) continue; //两个因子奇偶性不同
int p = (diff / t + t) / 2;
int x = p * p - a[i];
if (x < 0) continue;
int cnt = 0;
for (int k = 1; k <= n; k++) {
debug("a[k]+x", a[k] + x);
if (check(a[k] + x)) cnt++;
}
res = max(res, cnt);
}
}
}
cout << res << endl;
}

signed main() {
IOS
#ifndef ONLINE_JUDGE
freopen("../test.in", "r", stdin);
freopen("../test.out", "w", stdout);
#endif
int _ = 1;
cin >> _;
while (_--) solve();
return 0;
}