HDOJ 5778 abs(質因數分解)


abs

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


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
 

Source


思路:
此題的意思是,給定任意x,求使|y-x|最小的y,並且y要滿足對它進行質因數分解后每個質因數的指數都是2。
特么的這個題從第一天晚上9點多一直到第二天下午三點才A掉,換了好幾種做法,最后A掉的感覺真的是太爽了。

       一開始的思路就是想用質因數分解的模板,從x向兩邊遍歷,將各個質因數的指數都儲存起來,然后判斷,但是用這個方式的結果就是,T掉T掉再T掉,根本運行不起來,看起來很簡單的東西常規方法竟然不行。
       后來又想用打素數表的方式,看是不是能夠快一點,畢竟這樣的方法會比第一種方法快很多,不用對每個每個質數多次遍歷。但是!做了好久好久啊,突然發現一個問題!這個素數表要打到多少?他喵的題目里說n的數量姐最大是10的18次方,也就是說,可能存在一個10的9次方數量級的質數,它的平方是10的18次方數量級,且滿足題意,那這樣不就把素數表打到10的9次方了???咋不上天呢...但是我還是“腳踏實地”得打了一遍T-T到10的6次的時候程序就跑不動了...大哭
       那就再換啊!后來我就想,因為我之前是自己寫了一個分解質因數且儲存指數的函數,如果把這個函數直接放到函數里呢?應該會少一些東西...說不定就成功了呢hhhhh(內心一直幻想着A掉的那個畫面(*-*-*)生氣那就寫唄...寫着寫着就覺着不對勁,好像越寫越麻煩啊...而且如果質數分別是322222222,分明第一個指數就不是2了,難道以后的還需要遍歷?
       所以就產生了下面的改進版4.0,遍歷指數的時候,如果有指數不等於2,就continue。哈哈哈看起來好像快成功了的樣子!滿懷信心得再提交一次....特么的還是超時!!!抓狂奔潰啊....已經是晚上兩點了...就關機了,准備洗洗睡了...然而洗完澡之后又出來打開了電腦(這個沒志氣的貨...)這時候連樣例都過不了了...又重新找了一遍bug在哪,可是找不到啊啊啊啊啊啊。內心一萬個崩潰,真睡了...
       嶄新的一天!今天一定要A掉它!奮斗再次打了一遍,這次的改進措施是,我之前是用了兩個for循環來分別找y1和y2,這樣如果有相同的數要遍歷兩次,所以這次在for循環里的改變了一下,用flag1==true時表示y1還能再繼續找,flag2==true時表示y2還能再繼續找,如果有一個找到了它的flag就變成false,這樣當flag1!=false||flag2!=false的時候就可以遍歷到。但是...還是T...
       我開始懷疑人生了- - 試了一下把各個變量輸出,我發現如果找y1和y2聯系起來的話好像會產生連帶的副作用,所以還是把它們倆拆開了找。這次增加了一個細節,就是當x<=4的時候,它往下找是找不到的,所以當x<4時的結果是4-x,x==4時的結果是5,x>4時可以用上面寫的辦法來做。但是還是T
       啊啊啊啊啊要殺人啦發火仔細想了一下,大體的想法應該對,思路也對,應該就是對一些數據的處理細節有問題。在對1-100內的數都測試過后它們都可以過,但是如果數很大了的話,100000000000級別的程序就沒有反應了。開方!!!一下子把18次方數量級轉化為9次方數量級做了~~試想一下,如果y滿足它的質因數指數都是2,那么它開根號就是一個整數。但是還是會包含2^4開方后也是一個整數的情況,但是它2的指數在開方后是2,不是1。所以可以對開方后的數進行質因數,如果這個數可以被質因數分解且每個質因數的指數都是1,那么這個數就是符合的。哈哈哈哈哈哈哈哈哈哈哈哈真的好機智啊害羞這次提交了之后雖然是WA,但是不是T了!!又向成功進了一步!
      又分析為什么會WA,在輸出了幾對y1和y2后,我發現它們在向上找的時候y1都是正確的,但是在向下找的過程中y2卻不是它本該出現的值。我的y2是從(int)sqrt(x)開始向下找的,WA了。試想一下,如,如果開完根號是66.6,那么它向下找的話應該從66開始,也就是(int)sqrt(x);如果向上找的話就是從67開始找,也就是(int)sqrt(x)+1。這題提交就AC掉了~~~~
       最終版本是加強版8.0,總共提交了17次...最后過的時候真的是開心...

貼上我的終極強化版8.0代碼:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define maxn 100000

long long a[maxn];
long long b[maxn];

bool factor(int n)
{
    for(int i=2;i<=sqrt(n);i++){
		if(n%i==0){
			while(n%i==0){
				n=n/i;
				if(n%i==0) return false;
			}
		}
	}
	return true;
}

int main()
{
    int num;
    scanf("%d",&num);
    while(num--)
    {
        long long xx;
        long long x;
        long long y;
        scanf("%lld",&xx);
        x=(int)sqrt(xx);
        y=x+1;
        long long cnt=0;
        long long y1=0,y2=0;
        
        bool flag=false;
        
        if(xx<4)
        {
        	cout<<4-xx<<endl;
        	continue;
        }
        if(xx==4)
        {
        	cout<<5<<endl;
        	continue; 	
        }
        
        
        for(long long j=1;;j++)
        {
	        if(factor(x+j)==true)
			{
					y1=(x+j)*(x+j);
					break; 
		 	}      
        
        }
        
         cnt=0;
         for(long long j=1;;j++)
        {
        	if(fabs(y1-xx)<=fabs((y-j)*(y-j)-xx))
        	{
        		break;
        	}
            else if(factor(y-j)==true)
			{
					y2=(y-j)*(y-j);
					break;
		 	} 
	    } 
       // cout<<y1<<" "<<y2<<endl;
        long long s=min(fabs(y1-xx),fabs(y2-xx));
        printf("%lld\n",s);
    }
} 

希望我能在ACM道路上越走越遠...



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



正整數的質因數分解 hdu 5108 質因數分解 1-5-43:質因數分解 Sigma Function (質因數分解) POJ 1142 質因數分解 初級-質因數分解 C++質因數分解 質因數分解算法 XJOI 1003 質因數分解 43:質因數分解
 
粤ICP备14056181号  © 2014-2021 ITdaan.com