HDU 5778 乱搞

abs


Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)




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



题意:给你一个x,找出一个y,满足y>=2,x-y的绝对值最小,y分解质因子,每个质因子只有两个。


思路:x是10^18,且y满足每个质因子有两个,所以可以开方y,使得y的每个质因子只有一个,x的规模就降为了10^9,用线性素数筛找出10^5中所有素数,因为10^5^2>10^9,所以我们只需要找出10^5内的即可,然后对x进行左右暴力。注意x<4要特判,因为最小的符合条件的y是4。


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef __int64 ll;
ll prime[100005],num[100005],cnt=0;
int main(){
    prime[0]=prime[1]=1;
    ll i,j,t,n,m1,m2,m3,m4;
    for(i=2;i<=100000;i++){
        if(!prime[i])num[++cnt]=i;
        for(j=2;j*i<=100000;j++){
            prime[j*i]=1;
            if(!(i%j)) break;
        }
    }//线性素数筛
    ll sum=1;
    scanf("%I64d",&t);
    while(t--){
        //int flag=0;
        scanf("%I64d",&n);
        if(n==1){
        	printf("3\n");
        	continue;
        } 
        else if(n==2){
        	printf("2\n");
        	continue;
        }
        else if(n==3){
        	printf("1\n");
        	continue;
        }
        else if(n==4){
        	printf("0\n");
        	continue;
        }
        m1=sqrt(n);m2=m1+1;
        int ff;
        for(;;){
            if((n-m1*m1)<(m2*m2-n)){//如果左边优于右边
                m3=m1;
                ff=0;
                for(j=1;num[j]*num[j]<=m3;j++){
                    if(m3%num[j]==0) m3/=num[j];//分解质因子
                    if(m3%num[j]==0){//如果某个质因子个数大于1,那此数就GG
                        ff=1;break;
                    }
                }
                m1--;//m1往左缩小
                if(ff) continue;
                printf("%I64d\n",n-(m1+1)*(m1+1));
                break;
            }
            else{
                ff=0;
                m4=m2;
                for(j=1;num[j]*num[j]<m4;j++){
                    if(m4%num[j]==0)m4/=num[j];//同理
                    if(m4%num[j]==0){
                        ff=1;break;
                    }
                }
                m2++;
                if(ff)continue;
                printf("%I64d\n",(m2-1)*(m2-1)-n);
                break;
                
            }
        }
    }
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值