设我们要加的数字是 m,得到的结果是 l 的平方。
那么,我们就要找到两个正整数 m, l,满足 x + m^2 = l^2,其中,我们关心的是 m。
m^2 移项得 x = l^2 - m^2,平方差公式变形得 x = (l+m)(l-m)
接下来,可以通过分类讨论奇偶性的方法来解决,该讨论的是 l+m 的奇偶性。
如果 l+m 是偶数,那么 l-m 也是偶数,两个偶数相乘,结果一定是 4 的倍数,所以,当 x 是偶数时,只有为 4 的倍数才有解。
因为 x 是偶数,所以必定存在 2 这个质因子,我们就可以设 l-m=2,对应 l+m 就是 x/2,利用和差公式求出大数等于 x/4+1,小数就是 x/4-1。
又来讨论 x 的正负性,如果是正数,对应的 l 就是大数,可我们关心的是 m,所以,在x 为正,且为 4 的倍数下,x/4-1 是一个合法的解,如果是负数,那么 m 就大于 l 了,应该求大数,所以,在x 为负,且为 4 的倍数下,|x|/4+1 是一个合法的解
偶数讨论完毕,讨论奇数。
奇数要简单一些,因为 l+m 和 l-m 就都是奇数了,x 也是奇数,用上面的方法,设 l-m=1,l+m 就是 x,利用和差公式求出大数等于 (x+1)/2,小数就是 (x-1)/2。
又来讨论 x 的正负性,如果是正数,对应的 l 就是大数,可我们关心的是 m,所以,在x 为正,且为奇数下,(x-1)/2 是一个合法的解,如果是负数,那么 m 就大于 l 了,应该求大数,所以,在x 为负,且绝对值为奇数下,(|x|+1)/2 是一个合法的解
然后就把上面的所有结论拼在一起就算数了。
#include <bits/stdc++.h>
using namespace std;
int main() {
int q;
long long x;
scanf("%d", &q);
while (q--) {
scanf("%lld", &x);
if (x % 2 == 0) {
if (x % 4 == 0) {
if (x > 0) printf("%lld\n", x / 4 - 1);
else printf("%lld\n", abs(x) / 4 + 1);
} else puts("-1");
} else {
if (x > 0) printf("%lld\n", (x - 1) / 2);
else printf("%lld\n", (abs(x) + 1) / 2);
}
}
return 0;
}
|