hdu 5778 算复杂度

来源:互联网 发布:爱棋艺国际象棋软件 编辑:程序博客网 时间:2024/04/29 17:33



链接:戳这里


abs

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description
Given a number x, ask positive integer y≥2, that satisfy the following conditions:
1. The absolute value of y - x is minimal
2. To prime factors decomposition of Y, every element factor appears two times exactly.
 
Input
The first line of input is an integer T ( 1≤T≤50)
For each test case,the single line contains, an integer x ( 1≤x≤1018)
 
Output
For each testcase print the absolute value of y - x
 
Sample Input
5
1112
4290
8716
9957
9095
 
Sample Output
23
65
67
244
70


题意:

给定一个数x(1<=x<=1e18),求正整数y≥2,使得满足以下条件:
1.y-x的绝对值最小
2.y的质因数分解式中每个质因数均恰好出现2次。


思路:

x的范围太大导致你打表都处理不了。

我们考虑一个点,首先y的质因数分解每个质因数恰好出现两次。

我们取根号x,就会使得每个质因数只出现一次。(后面的x都默认已经开了根号

而我们要找出第一个大于x或者小于等于x的这样一个数y使得满足条件

这样的数y肯定距离x不会太远。因为素数一次方再加上各个素数之间的乘积会使得y与x的间隙小。

那么我们暴力去判断第一个<=x的素数y或者素数之间的乘积以及第一个>=x的素数y或者素数之间的乘积y

枚举的当前数y,它必须只能整除可以整除的素数仅1次,如果当前整除超过了两次,break,继续往下找。

仔细想一下,这样找下去肯定会遇到一个当前y就是素数。嗯,所有暴力的话根本复杂度也就那么一点


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<iomanip>#include<cmath>#include<bitset>#define mst(ss,b) memset((ss),(b),sizeof(ss))///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;#define INF (1ll<<60)-1#define Max 1e9using namespace std;ll n;bool pd(ll x){    ll t=sqrt(x+0.5);    for(ll i=2;i<=t;i++){        if(x%i==0){            x/=i;            if(x%i==0) return true;        }    }    return false;}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%I64d",&n);        ll mid=sqrt(n+0.5);        ll x=mid,y=mid+1;        while(x && pd(x)) x--;        while(y && pd(y)) y++;        ll ans=y*y-n;        if(x>1) ans=min(ans,n-x*x);        ///cout<<x*x<<" "<<y*y<<endl;        printf("%I64d\n",ans);    }    return 0;}



0 0
原创粉丝点击