hdu 5778 算复杂度



链接:戳这里


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
#include
#include
#include
#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#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 1e9
using 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<



你可能感兴趣的:(简单数学,姿势技巧+构造)