HDU 6216 A Cubic number and A Cubic Number【数学思维+枚举/二分】

Problem Description

A cubic number is the result of using a whole number in a multiplication three times. For example, 3×3×3=27 so 27 is a cubic number. The first few cubic numbers are 1,8,27,64 and 125 . Given an prime number p . Check that if p is a difference of two cubic numbers.
 
Input
The first of input contains an integer T (1T100) which is the total number of test cases.
For each test case, a line contains a prime number p (2p1012) .
 
Output
For each test case, output 'YES' if given p is a difference of two cubic numbers, or 'NO' if not.
 
Sample Input
10 2 3 5 7 11 13 17 19 23 29
 
Sample Output
NO NO NO YES NO NO NO YES NO NO
 
Source
 
【题意】:询问一个质数p是否可以写成两个立方数的差。
【分析】:

x^3-y^3
=(x^3-x^2*y)+x^2*y-(y^3-x*y^2)-x*y^2
=x^2(x-y)-y^2(y-x)+xy(x-y)

=(x-y)(x^2+xy+y^2)=p(p是质数)——> x-y=1以及x^2+xy+y^2=p

代入消元:p=3x^2+3x+1

【代码】:

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<set>
#include<string>
using namespace std;

int main()
{
    int t,p,flag;
    scanf("%d",&t);
    while(t--)
    {
        flag=0;
        scanf("%d",&p);
        for(int i=1;i<=1e6+10;i++)
        {
            if(3*i*i+3*i+1==p)
            {
                flag=1;
                break;
            }
        }
        if(flag) printf("YES
");
        else printf("NO
");
    }
    return 0;
}
View Code
#define _CRT_SECURE_NO_WARNINGS  
#include <iostream>  
#include <cstdio>  
#include <algorithm>  
#include <cstring>  
#include <string.h>  
#include <string>  
#define ll long long  
  
using namespace std;  
  
const int MAXN = 1e6 + 5;  
ll tab[MAXN];  
  
void init()  
{  
    for (ll i = 0;i < MAXN;++i)  
        tab[i] = 3 * i*i + 3 * i + 1;  
}  
  
  
int main()  
{  
    int T;  
    scanf("%d", &T);  
    init();  
    for (int i = 1;i <= T;++i)  
    {  
        bool flag = false;  
        ll v;  
        scanf("%I64d", &v);  
        int left = 0, right = MAXN-1;  
        int mid = (left + right) >> 1;  
        while (left <= right)  
        {  
            if (v == tab[mid])  
            {  
                flag = true;  
                break;  
            }  
            else if (v > tab[mid])  
                left = mid + 1;  
            else  
                right = mid - 1;  
            mid = (left + right) >> 1;  
        }  
        if (flag)  
            printf("YES
");  
        else  
            printf("NO
");  
    }  
    //system("pause");  
    return 0;  
} 
预处理+二分查找//参考
原文地址:https://www.cnblogs.com/Roni-i/p/7538553.html