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
#include
#include
#include
#include
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]


你可能感兴趣的:(乱搞)