abs
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 491 Accepted Submission(s): 176
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
Source
解题思路:解决本题的关键是怎么处理一个数的所有质因子都只出现两次,所以我采用的做法先对这个数开根号(原来数的范围太大),直接对这个新的数进行质因数分解O(sqrt(n)),然后判断所有因数的乘积是否等于它本身。剩下就是对给定的数开根号然后暴力的上下枚举啦~ (^_^)
这道题其实应用了一个隐含的素数定理:任意相邻的两个素数之间的距离接近lg(n),也就保证了本题的时间复杂度一定可行~
心得:当时比赛的时候写了40分钟,结果一直WA,比完后才突然意识到题目说y>=2.....T^T 给一组数据(iput:1 1 )(output:3),好多人都是输出0的...
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <utility>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
bool factor(ll n)//这里对一个整数进行质因数分解
{
ll m = 1;
ll num = n;
set<int>ret;
int sqrtn = int(sqrt(n));
for(int div = 2; div <= sqrtn; div++)
{
while(n%div==0)
{
n /= div;
ret.insert(div);
}
}
if(n>1) ret.insert(n);
set<int>::iterator it;
for(it=ret.begin();it!=ret.end();it++)
m *= (*it);
if(m==num) return true;//判断所有质因数的乘积是否等于其本身
return false;
}
int main()
{
//freopen("test.txt","w",stdout);
int t;
cin>>t;
ll x;
while(t--)
{
cin>>x;
ll temp = int(sqrt(x));
ll a,b;
ll ans;
ll ans1 = 1e18;//初始化为一个比较大的数即可,应该不用这么大
ll ans2 = 1e18;
a = temp + 1;
b = temp;
while(1)//向上查找
{
if(a+1>=1000000000)
break;
if(factor(a))
{
ans1 = abs(a*a-x);
break;
}
a++;
}
while(1)//向下查找
{
if(b<2)//注意判断这个结束条件,y>=2
break;
if(factor(b))
{
ans2 = abs(b*b-x);
break;
}
b--;
}
ans = min(ans1,ans2);
cout << ans << endl;
}
return 0;
}