链接:戳这里
abs
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
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 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<<x*x<<" "<<y*y<<endl;
printf("%I64d\n",ans);
}
return 0;
}