码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5778

时间:2016-08-01 12:01:01      阅读:105      评论:0      收藏:0      [点我收藏+]

标签:

题意:

给定一个数x,求正整数y≥2y\geq 2y2,使得满足以下条件:

1.y-x的绝对值最小

2.y的质因数分解式中每个质因数均恰好出现2次。

思路:

开根号上下搜索,枚举素数的方,判断是否成立,题目数据1e18,开根1e9,故判断是否包含素数方只需要枚举4*1e4内的素数就够了,完全在可解范围之内;

 

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <cstdio>
#include <cstring>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <map>
#include <set>

using namespace std;
#define ll long long
const long long inf=(ll)1e15+88;

const int maxn=(int)1e4+88;
const int mod=1000000007;

ll a[maxn];
bool ab(ll mid)
{
    for(int i=2;i<maxn;i++)
    {
        if(a[i]==0&&mid%(i*i)==0)
            return false;
    }
    return true;
}
ll myabs(ll a)
{
    if(a>0)return a;
    return -a;
}
int main()

{
//    freopen("1010.in", "r", stdin);
//     freopen("out.txt", "w", stdout);
    for(int i=0;i<maxn;i++)
        a[i]=0;
    for(int i=2;i<maxn;i++)
    {
        if(a[i]!=0)continue;
        for(int q=2;i*q<maxn;i++)
        {
            a[i*q]=1;
        }
    }
    int t;
    cin>>t;
    while(t--)
    {
        ll n;
        cin>>n;
        if(n<=4)cout<<4-n<<endl;//因为最小素数方为4,小于4向前搜索没意义,故特判
        else {
        ll m=(ll)sqrt(n);
        ll l=m,r=m;

        for(l;l>=2;l--)//开根向下去整
        {
            if(ab(l))
                break;
        }
        for(++r;r;r++)//因为开根强转相当于开根向下取整,在其下,r需在其上,++r正好包含
        {
            if(ab(r))
                break;
        }

        cout<<min(myabs(n-l*l),myabs(r*r-n))<<endl;
        }
    }
    return 0;
}

    注意:n之内的合数总可以通过根号n的区间来求解!!!时间复杂度即可降!!!

 

 

 

 

 

 




hdu 5778

标签:

原文地址:http://www.cnblogs.com/aishuijdemiaomiao/p/5725231.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!