題目描述所謂孿生素數指的是間隔為2的相鄰的素數,他們之間的距離已經近得不能再近了,就像孿生兄弟一樣,最小的孿生素數是(3,5),在100以內還有(5,7),(11,13),(17,19),(17,19),(29,31),(41,43),(59,61),(71,73),總計8組。
但隨著數字的增大,孿生素數的分布越來越稀疏,尋找起來也變得困難,那會不會在超過某個界限之后就再也沒有孿生素數了呢?
孿生素數有無窮多個!這個猜想稱為孿生素數猜想,但至今沒有被嚴格證明,但借助計算機我們已經確實可以找到了任意大范圍內的所有孿生素數對。
接下來你的任務就是計算不大于n的范圍內的孿生素數對的個數!
解答要求時間限制:60000ms, 內存限制:64MB
輸入輸入包含多組測試,每組測試占一行,包含一個整數n(1<n<100000001),輸入到文件末尾結束。
輸出輸出孿生素數的對數。
樣例輸入樣例 1 復制
10100
輸出樣例 1
28
分析
看似簡單的題,往往坑會很多,時間復雜度、空間占用大小都有限制,下面的解題思路很值得學習。
(來源于網絡)
算法總體思路,因為題目有時間及空間要求,計算素數如果采用遍除法會超時,所以采用篩法求素數,
算法思路:創建一個大小為100000000的int型數組,第i個位置表示i是不是素數,初始化全部為0,開始排除不是素數的數,從2開始將2的所有倍數對應的數組位置置為1,表示其不是素數,
再從數組上取下一個沒有被排除的數,將其所有倍數對應位置置為1,以此類推,直到取到的下一個數大于10000,此時在100000000的范圍內已經沒有合數了,數組初始處理完畢,
有了素數表,然后按輸入的n累加個數即可
// 空間優化思路,因為大小為100000000的int型數組已經超過了題目要求的64M的空間限制,而我們每個int其實只有取值0和1,
所以為了節省空間,我們可以采用位操作,將一個int作為32位二級制數來操作,可以將空間使用率縮小32倍,此時此算法已經可以滿足題目要求的時間及空間限制// 除此以外,大于2的偶數很明顯并不是素數,我們可以默認只處理奇數,同理3的倍數也不是素數,我們也可以在將它們排除在外,
排除這兩個數的倍數不予處理之后,我們的數組大小可以繼續縮小1/3(約4M左右),處理的數據量也減少到原來的1/3.// 排除2和3倍數的辦法:2和3的倍數以6為周期的周期性分布,比如6-11之間,不是2和3倍數的只有7(6+1)和11(6+5),12-17之間,只有13(6*2+1)和(6*2+5),
只有6*n+1和6*n+5的數不能被2或者3整除,才可能為素數,因此,我們把需要處理的數據初始化為2,3,5,7,11,13,17,19,23,25...,
此時,已經不用關心2和3的倍數,從5開始處理,將5*5,5*7,5*11...設置為非素數,然后是7*7,7*11,7*13...// 由于排除了2和3的倍數,數組位置跟數字之間已經不是一一對應的,增加位置與數字之間的轉換方法計算一下即可
java代碼實現
import java.util.BitSet;import java.util.Scanner;//孿生素數public class twinsPrime { static final int MAX=100000000; static BitSet bs = new BitSet(MAX/3+2); public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); init(); while(in.hasNextInt()){ int n = in.nextInt(); System.out.println(count(n)); } } //統計n內的孿生素數的對數 public static int count(int n){ int count=1; if(n<5||n>MAX){ return 0; } for(int i=2;i<bs.size();i+=2){ if(getNumber(i+1)<=n && checkBit(i) && checkBit(i+1)){ count++; } } return count; } //初始化孿生素數 public static void init(){ int number; for(int i = 2;i<bs.size();i=getNearlyPosition(number+2,true)){ number = getNumber(i); if(number > Math.sqrt(MAX)){ return; } // 從后往前處理,避免從前往后處理被覆蓋 int lastIndex = getNearlyPosition(getNumber(MAX/3+2)/number,false); for(int j = lastIndex;j>=i;j--){ while(!checkBit(j)){ j--; } int position = getPosition(number*getNumber(j)); if(position != 0){ changeBit(position); } } } } //獲取離指定數字最近的未排除數字的索引 public static int getNearlyPosition(int number,boolean isAdd){ int position; while(number <= MAX){ position = getPosition(number); if(position != -1 && checkBit(position)){ return position; }else if(isAdd){ switch(number%6){ case 1:number+=4;break; case 5:number+=2;break; case 0:number+=1;break; case 2:number+=3;break; case 3:number+=2;break; case 4:number+=1;break; } }else{ switch(number%6){ case 1:number-=2;break; case 5:number-=4;break; case 0:number-=1;break; case 2:number-=1;break; case 3:number-=2;break; case 4:number-=3;break; } } } return 0; } //獲取指定位置的數字 private static int getNumber(int index) { if(index > 1){ return index*3-1-(index&1); }else if(index == 1){ return 3; }else if(index == 0){ return 2; } return 1; } //求指定數字所在位置 private static int getPosition(int number){ int r = number%6; if(number>=4){ if(r==1||r==5){ return 2*(number/6)+(r==1?1:2); } return -1; }else if(number==2){ return 0; }else if(number==3){ return 1; }else{ return -1; } } /* *對指定位進行置1操作 *即不是素數 */ public static void changeBit(int index){ if(index>=bs.size() || index<0){ return; } bs.set(index); } /* *判斷指定位是0還是1,0返回true,1返回false *檢查指定位置是否是素數 */ public static boolean checkBit(int index){ if(index>bs.size() || index<0){ return false; } return !bs.get(index); }}
參考網址:
https://blog.csdn.net/qq_24034545/article/details/100725577
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
錯誤代碼118什么意思?錯誤代碼118是一個擴展鏈接錯誤,其中大部分是web服務器上的鏈接錯誤。解決方案:使用命令提示符重置網絡設置和DNS緩存。網站是指使用HTML(標準通用標記語言)等工具,按照一定規則在互聯網上顯示特定內容的網頁集合??傊?,網站是一種交流工具,人們可以通過它發布自己想公開的信息,或者利用網站提供相關的網絡服務。人們可以通過網絡瀏覽器訪問網站,獲取所需信息或享受網絡服務。網站是...
不見不散播放器播放曲目順序怎么調?歌曲的播放時順序是聽從你拷入儲存卡的先后順序來播放時的。要是你想遵循你的順序讓它來可以播放,可以到期待你的到來官網上下載一個“MP3排序工具”,這樣你就能聽從你要想的正常播放順序來可以播放。小說播放列表怎么調整順序?小說的播放列表,他就像是依據什么小說的那個設置里好的閱讀章節并且播放時的,假如想按照順序的話,像是是可以不實際更改后他那個設置,也就是他閱讀的那個模式...
如何評價多閃這款軟件?謝謝。歡迎關注黑桃。讓我們和小編談談這個新的帶有社會元素的多閃標題作品。我們來談談現在的社交軟件,騰訊的微信可以說是一個占主導地位的公司,它的家庭QQ也在下降,所以對于騰訊來說,它會盡力保持微信的社會地位,新版的微信7也就在于此,但是微信的努力不會減少競爭對手的努力,而且標題的內容有其自身的基礎,每天有2億5000萬用戶,微信的地位受到挑戰。這是多閃光燈。但是,如果它和微信完...