中文描述:
问题描述
给定一个数x,求正整数y≥2,使得满足以下条件:
1.y-x的绝对值最小
2.y的质因数分解式中每个质因数均恰好出现2次。
输入描述
第一行输入一个整数T(1≤T≤50) 每组数据有一行,一个整数x(1≤x≤1018)
输出描述
对于每组数据,输出一行y-x的最小绝对值
输入样例
5 1112 4290 8716 9957 9095
输出样例
23 65 67 244 70
#include <iostream>
#include <cmath>
#include <string.h>
using namespace std;
typedef long long ll;
bool divide(ll n){
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
while(n%i==0){
n=n/i;
if(n%i==0) return false;
}
}
}
return true;
}
ll sqr(ll x){
return x*x;
}
int main(){
// freopen("3.in","r",stdin);
// freopen("3.out","w",stdout);
int t;
scanf("%d",&t);
while(t--){
ll x;
scanf("%lld",&x);
ll x1=sqrt(x);
ll x2=x1+1;
if(x<4) printf("%lld\n",4-x);
else{
while(!divide(x1)){
x1--;
}
while(!divide(x2)){
x2++;
}
ll ans=min(abs(sqr(x1)-x),abs(sqr(x2)-x));
printf("%lld\n",ans);
}
}
}
题意其实是求一个y-x的绝对值最小,并且y中的质因子次数要么是0要么是2;
x的数量级是1e18,所以我们可以考虑把x开方后,寻找开方后的x附近的某个数,这个数质因子只能出现过1次;
将开方后的x取整,令x1为左范围,x2为右范围;
然后把范围都扩大到因子只出现一次的数就可以了
开始我其实是打算暴力在x开方周围解决的,后来对样例进行测试计算的时候发现了规律,说实话也不知道是自己运气好还是真的有能力去解决。。。