HDOJ 5780 abs(枚举)

abs

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1348    Accepted Submission(s): 476


Problem Description
Given a number x, ask positive integer  y2 , 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 (  1T50 )
For each test case,the single line contains, an integer x (  1x1018 )
 

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,求一个y,要求y的质因子分解式中每个质因子恰好出现两次,问y-x的最小绝对值?


真是GG啊,BC的时候想了一个小时,以为有什么高级姿势打表出这样的y,然后直接遍历出来呢......


题解: 对于任意的一个数n,他的质因子分解式是唯一的。 我们就可以就近枚举sqrt(x)附近的sqrt(y)就好了,对于sqrt(y)的质因子分解式每个质因子恰好是出现一次的。 我们可以打出1e5范围内的素数表,对于每个被枚举到的数,判断其质因子分解式是否会多次出现同一个质因子,若没有就是符合条件的sqrt(y)。 若sqrt(y)在1e5范围内没有质因子,那么就表示sqrt(y)本身就是质数。


代码如下:


/* *********************************************** 
   ┏┓   ┏┓     
 ┏┛┻━━━┛┻┓    神  
 ┃       ┃    兽 
 ┃   ━   ┃    保 
 ┃ ┳┛ ┗┳ ┃    佑
 ┃       ┃  
 ┃   ┻   ┃     代 
 ┗━┓     ┏━┛     码 
     ┃    ┃       无   
     ┃   ┗━━━┓     bug 
   ┃        ┣┓ 
   ┃         ┏┛ 
   ┗┓┓┏━┳┓┏┛  
    ┃┫┫ ┃┫┫  
   ┗┻┛ ┗┻┛  
************************************************ */  
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 100010
#define LL long long
#define INF 0x3f3f3f3f3f 
using namespace std;
int primes[maxn],a[maxn]={1,1};
int k=0;
LL ans,n;

void prime()
{
	LL i;
	LL j;
	for(i=2;i<maxn-10;++i)
	{
		if(!a[i])
		{
			primes[k++]=i;
			for(j=i*i;j<maxn-10;j+=i)
				a[j]=1;
		}
	}
}

bool judge(LL x)
{
	int i,j;
	LL p=x;
	for(i=0;i<k;++i)
	{
		j=0;
		while(p%primes[i]==0)
		{
			p/=primes[i];
			j++;
		}
		if(j>1)
			return false;
		if(primes[i]*primes[i]>p)
			break;
	}
	ans=min(ans,abs(n-x*x));
	return true;
}

int main()
{
	prime();
	int t;
	LL x,y;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%I64d",&n);
		x=sqrt(1.0*n);
		y=x+1;
		ans=INF;//一定要注意ans的初始值,要足够大 
		while(x>=2&&(!judge(x)))
			x--;
		while(!judge(y))
			y++;
		printf("%I64d\n",ans);
	}
	return 0;
}
/*
10
98765432123456789
*/ 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值