zoukankan      html  css  js  c++  java
  • BestCoder Round #85 hdu5778 abs(素数筛+暴力)

    abs

    题意:

    问题描述
    给定一个数x,求正整数y,使得满足以下条件:
    1.y-x的绝对值最小
    2.y的质因数分解式中每个质因数均恰好出现2次。
    输入描述
    第一行输入一个整数T
    每组数据有一行,一个整数x
    输出描述
    对于每组数据,输出一行y-x的最小绝对值
    输入样例
    5
    1112
    4290
    8716
    9957
    9095
    输出样例
    23
    65
    67
    244
    70

    题解:

    由于y质因数分解式中每个质因数均出现2次,那么y是一个完全平方数,设y=z*z,题目可转换成求z,使得每个质因数出现1次. 我们可以暴力枚举z,检查z是否符合要求,显然当z是质数是符合要求,由素数定理可以得,z的枚举量在logn级别 。

    上面是官方题解,再说我的理解:首先看范围是1e18,不好弄,但题里又说y的质因子出现2次,故想到要根号降到1e9,这样就可以素数筛 根号1e9 内的素数了,这样就可以判断在1e9内某个数是否为素数了。之后枚举就好了,题里说y-x的绝对值,所以前后都枚举,有一个符合条件的记录,然后break就好了,PS:向前枚举到2就可以了,因为题里说y>=2。

    再说下怎么判断z,也就是我写的ok函数,就直接把 根号1e9 内素数循环一次就好了,如果可以取余0 就/=,之后在判断这个是否还是取余0,如果还是就不符合,因为要求z的质因数都只出现1次。当最后/=为1的时候就可以返回真了,最后如果一次取余==0都没有,就证明这是素数,所以也返回真。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int INF=0x3f3f3f3f;
    const ll LINF=0x3f3f3f3f3f3f3f3f;
    #define PU puts("");
    #define PI(A) cout<<A<<endl
    #define SI(N) cin>>N
    #define SII(N,M) cin>>N>>M
    #define cle(a,val) memset(a,(val),sizeof(a))
    #define rep(i,b) for(int i=0;i<(b);i++)
    #define Rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define reRep(i,a,b) for(int i=(a);i>=(b);i--)
    #define dbg(x) cout <<#x<<" = "<<x<<endl
    #define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
    #define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
    const double EPS= 1e-9 ;
    
    /*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */
    
    const int MAXN= 40000 + 9 ;
    
    int prime[MAXN],K;
    bool is_prime[MAXN];
    int sieve(int n)
    {
        int p=0;
        for (int i=0;i<=n;i++) is_prime[i]=true;
        is_prime[1]=is_prime[0]=false;
        for (int i=2;i<=n;i++)
        {
            if (is_prime[i])
            {
                prime[p++]=i;
                for (int j=2*i;j<=n;j+=i) is_prime[j]=false;
            }
        }
        return p;
    }
    bool ok(ll x)
    {
        bool f=0;
        rep(i,K)
        {
            if (x%prime[i]==0)
            {
                f=1;
                x/=prime[i];
                if (x%prime[i]==0)
                    return false;
                if (x==1) return true;
            }
        }
        if (!f) return true;
    }
    int main()
    {
        iostream::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
        K=sieve(MAXN);
        int o;
        SI(o);
        while(o--)
        {
            ll x;
            SI(x);
            ll sqx=sqrt(x);
            ll mi=LINF,ma=LINF;
            for (int i=sqx+1;i<1e9+9;i++)
            {
                if (ok(i))
                {
                    ma=i;
                    break;
                }
            }
            for (int i=sqx;i>=2;i--)
            {
                if (ok(i))
                {
                    mi=i;
                    break;
                }
            }
            PI(min(llabs(ma*ma-x),llabs(mi*mi-x)));
        }
        return 0;
    }
  • 相关阅读:
    出差(十四)确定
    出差(十三)协作
    出差(十二)现状
    出差(十一)变化
    手机的惊险一幕
    出差(十)重复
    出差(九)假象
    出差(八)了解
    出差(七)学习
    Servlet程序开发-- servlet跳转
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5724941.html
Copyright © 2011-2022 走看看