BestCoder Round #82 ztr loves mat

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5675

题意:给出一个正整数n,问可否找到一个正整数x和y,使得n = x^2-y^2。

n的范围是10^18,怎么样也不可能暴力打表,所以这肯定是一个数学题,起初小编没有发现规律,于是动笔写了一下,立马就发现了其中的规律。

我们先写几个平方数:0,1,4,9,16,25,36,49……

观察相邻数之间的差:1,3,5,7,9,11,13……

不难发现这是连续的奇数,仔细一想,(a+1)^2-a^2 = 2a+1,也就是说如果n为奇数,那么肯定会有对应的一组相邻的x和y满足条件,再思考,如果n是偶数要满足条件需要满足什么条件,因为x^2 - y^2 实际就是几个连续的奇数的和,所以要达到和为一个偶数,就必须是偶数个奇数相加,n = (2a+1) + ((2a+1)+2) + ((2a+1)+4) + …… + ((2a+1)+2*2k) = 2k*2a + (2+4k)*2k/2 = 4ka + 4k(k+1),不难发现,要达到这个条件必须是4的倍数才行,所以我们的判定条件就是奇数或者是4的倍数的偶数。

官方题解给出的证明是(a+1)^2-(a-1)^2 = 4*a……小编个人觉得这种证明有点牵强啊,不具有普遍性。

这次BC因为数据出错的原因unrated了,这个题的这个特判就是其中一个原因,因为x和y必须是正整数,所以其实1和4是达不到条件的,因为1和4只有可能是1^2-0,2^2-0才能达到,但是实际上是取不到0的,所以我们必须得特判一下1和4

#include <cstdio>
#include <cmath>
#include <cstdlib>
#define LL __int64
int main()
{
    LL T;
    scanf("%I64d",&T);
    while(T--)
    {
        LL n;
        scanf("%I64d",&n);
        //n = abs(n);
        if(n == 1 || n == 4)
        {
            printf("False\n");
            continue;
        }
        if(n%2 != 0) printf("True\n");
        else if(n%4 == 0) printf("True\n");
        else printf("False\n");
    }
    return 0;
}


你可能感兴趣的:(BestCoder Round #82 ztr loves mat)