noip模拟赛 立方数2

题目描述
LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数,例如1,8,27就是最小的3个立方数。
LYK还定义了一个数叫“立方差数”,若一个数可以被写作是两个立方数的差,则这个数就是“立方差数”,例如7(8-1),26(27-1),19(27-8)都是立方差数。
现在给定一个数P,LYK想要知道这个数是不是立方差数。
当然你有可能随机输出一些莫名其妙的东西,因此LYK有T次询问~
这个问题可能太难了…… 因此LYK规定P是个质数!

输入格式(cubicp.in)
第一行一个数T,表示有T组数据。
接下来T行,每行一个数P。

输出格式(cubicp.out)
输出T行,对于每个数如果是立方差数,输出“YES”,否则输出“NO”。

输入样例
5
2
3
5
7
11

输出样例
NO
NO
NO
YES
NO


数据范围
对于30%的数据p<=100。
对于60%的数据p<=10^6。
对于100%的数据p<=10^12,T<=100。

分析:看到立方差就应该能想到立方差公式吧:a^3-b^3 = (a-b)(a^2 + ab + b^2),因为p为质数,所以a-b = 1,a^2+ab+b^2=p或a-b=p,a^2+ab+b^2=1,化简一下,发现只有前一种情况成立,根据△是完全平方数,b是正整数,就能知道p是否满足要求.

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
int T;
ll p;

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%lld", &p);
        ll t = (ll)sqrt(12 * p - 3);
        if (t * t != 1LL*12 * p - 3)
        {
            printf("NO
");
            continue;
        }
        if ((t - 3) % 6 == 0)
            printf("YES
");
        else
            printf("NO
");
    }

    return 0;
}
原文地址:https://www.cnblogs.com/zbtrs/p/7756814.html