0%

Hdu 5778 abs (暴力_二分)

题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5778
题目大意:
给定一个数x,求正整数y2y\geq2,使得满足以下条件:
1.yxy-x的绝对值最小
2.y的质因数分解式中每个质因数均恰好出现2次。

简单分析:
y的质因数分解式中每个质因数均恰好出现2次,显然y是个完全平方数,但不是所有的完全平方数满足每个质因数恰好出现2次,yxy-x绝对值最小的数,显然当y\sqrt{y}x\sqrt{x}附近且满足条件时,绝对值最小,对x\sqrt{x}分解质因数,若有一个因数出现2次以上,则不满足条件,减小此值,继续向下搜索,由于这样的数出现的非常频繁,所以复杂度不会爆,然后再从x+1\sqrt{x}+1开始向上查找,直到找到一个满足的值,比较两次找到的数的平方与x的绝对值,最后输出小的那个
注1:第二次从x+1\sqrt{x}+1开始主要是为了防止某个数x,x\sqrt{x}满足条件,但x+1\sqrt{x}+1也满足,且答案更小,
注2:由于y2y\geq2,还需要加特判当x4x\leq4时,y都只能等于4,4为最小的满足条件的y值,此时当输出4x4-x

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<math.h>
using namespace std;

long long int x,y,temp;

bool cha(long long kai)
{
long long int i;
for(i=2;i*i<kai;i++)
{
if (kai%i==0)
{
kai/=i;
if (kai%i==0)
return true;
}
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld",&x);
long long kai1=(long long)sqrt(x);
long long kai2=kai1;
while(cha(kai1))
{
kai1=kai1-1;
}
y=abs(kai1*kai1-x);
kai2++;
while(cha(kai2))
{
kai2=kai2+1;
}
y=min(y,abs(kai2*kai2-x));
if (x<=4)
y = 4-x;
printf("%lld\n",abs(y));
}
return 0;
}