【轉】如何用 C/C++ 求 1 到 1000 內的所有完全數
[n for n in range(1, 1000)
if sum(k for k in range(1, n) if n%k == 0) == n]
另一方面這又是個數學題目。可以想見會有人想出一些辦法去做「優化」,卻輕視程式設計碼程式碼之前的數學與演算法上的分析。實際上,如果未經深思熟慮,這類優化能起到的效果甚微,在本質上不能減少多少運算。因此,倒不如仔細從數學角度好好看看這個問題,給出一個完全不一樣的演算法,或許會讓這個原本不起眼的小題目吃起來更有嚼頭一些。---
由 Euclid-Euler 定理,一個數 n 是偶完全數,當且僅當,其中 是一個梅森素數。
奇完全數是否存在,是當今數論中未解決的問題。但
於是現在問題歸結到求一組較小的 k 使 是梅森素數,然後套用 Euclid-Euler 定理公式計算。
驗證梅森素數的方法,較為有效的是 Lucas–Lehmer 檢驗法。即定義
從而 是素數當且僅當
其中 k 是奇數,由梅森素數的性質,等價於 k 是奇素數。k 為偶數 2 則是特殊情形, 是素數。
為方便計算,事實上並不需要求出所有的 ,只要求得餘數即可(否則中間結果會很大)。而這個條件用計算機非常容易驗證。
由於只要求 1000 以內的完全數,因此用 n 的表示式粗略地估計,最多隻要求出 1000 以內的梅森素數。注意到 2 的 10 次方即超出 1000,因此只需要考慮 k 小於 10 的情形進行驗證。因此這也是很有效的演算法,遠好於用定義試除計算。
下面是程式碼:
#include <iostream>
inline long mersenne(int k)
{
return (1L << k) - 1L;
}
// euclid_euler(k) is perfect if mersenne(k) is prime
// http://en.wikipedia.org/wiki/Euclid%E2%80%93Euler_theorem
inline long euclid_euler(int k)
{
return ((1L<<k) - 1L) << (k-1);
}
// return true if mersenne(k) is prime
bool lucas_lehmer_test (int k)
{
// special case: merssene(2) = 3 is prime
if (k <= 2)
return k == 2;
// Lucas-Lehmer test
// http://mathworld.wolfram.com/Lucas-LehmerTest.html
long s = 4;
long m = mersenne(k);
for (int i = 0; i < k - 2; ++i) {
s = s * s - 2;
if (m != 0)
s %= m;
}
return s == 0;
}
int main()
{
const long perfect_number_bound = 1000;
for (int k = 0; euclid_euler(k) < perfect_number_bound; ++k) {
if (lucas_lehmer_test(k))
std::cout << euclid_euler(k) << '\n';
}
return 0;
}
// Result:
// 6
// 28
// 496
相關推薦
求1-1000內所有的完數(一個數如果恰好等於它的因子之和,這個數就稱為“完數”。如6就是1個完數: 6=1+2+3,因子數就是所有可以整除這個數的數,但是不包括這個數自身.比如15的
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _3a { c
求1~1000之間的完全數
#include<iostream.h> void main() { int a,b,sum=0; for(a=6;a<1000;a++) { for(b=1;b<a;
【轉】如何用 C/C++ 求 1 到 1000 內的所有完全數
這是個小題目,按定義窮舉算是基本的練習,並太多特別值得說的地方。選個合適的語言,也就是一兩行程式碼按定義表示出來,比如 Python: [n for n in range(1, 1000) if sum(k for k in range(1, n) if n%k == 0) == n] 另一方面
【Coding】用篩法求素數的C++實現(附100000以內素數表)
#include <cstdio> #include <cstring> using namespace std; #define MAXN 1000000+100 bool arr[MAXN]; void findPrime(int
【轉】VS2010中 C++創建DLL圖解
-a rar cls ret ria endif -s pan 項目 標簽: dllc++2010threadlibraryc 本文章已收錄於: .embody { padding: 10px 10px 10px; margin: 0 -20px; b
【轉】幾種C/C++開發的開源搜尋引擎
(1)CLucene CLucene是Lucene的一個C++埠,Lucene是一個基於java的高效能的全文搜尋引擎。CLucene因為使用C++編寫,所以理論上要比lucene快。 (2)Xapian Xapian是一個用C++編寫的全文檢索程式,他的作用類似於Java的lucene。儘管在Java世
【轉】深入理解C++的動態繫結和靜態繫結
為了支援c++的多型性,才用了動態繫結和靜態繫結。理解他們的區別有助於更好的理解多型性,以及在程式設計的過程中避免犯錯誤。 需要理解四個名詞: 1、物件的靜態型別:物件在宣告時採用的型別。是在編譯期確定的。 2、物件的動態型別:目前所指物件的型別。是在執行期決定的。物件的
【轉】 用BlazeMeter錄制JMeter測試腳本
打開 測試的 文件 wid mbo 自己的 .net 一個 tar 工具: 1,JMeter 2,Chrome 3,BlazeMeter 4,SwitchyOmega(如果需要代理) 步驟: 以上工具準備好以後就可以錄制JMeter的測試腳本了, 在Chrome中點擊B
【轉】用Python建立最簡單的web服務器
web服務 localhost 服務器 pos 根目錄 cal body -m -- 利用Python自帶的包可以建立簡單的web服務器。在DOS裏cd到準備做服務器根目錄的路徑下,輸入命令: python -m Web服務器模塊 [端口號,默認8000]
【轉】用宏定義代替printf函數
tar 版本 data eas article target else define ref 問題提出 有時候我們想用宏定義來決定是編譯debug版本的代碼還是release的代碼,dubug版本的代碼會通過printf打印調試信息,release版本的代碼則不會。我們總不
【轉】用python比對數據庫表數據的腳本
%s import gpa post parse pwd 基本原理 -- get 最近在做一個數據庫異構復制的項目,客戶表示需要一個數據比對的工具,我就自己寫了一個異構數據庫的比對python腳本.這個比對腳本只能比對數量,不能比對具體的記錄.使用的sql語句也是最基礎的s
【轉】用Java實現網路語音訊號傳送
本文轉載自部落格:https://www.aliyun.com/jiaocheng/347518.html ----------------------------------------------------------------------------------------------
【轉】用jsmin批量壓縮JS的批處理檔案
在網頁中動態載入的 JavaScript 對於頁面顯示的速度影響甚多,不得不注意! 尤其是很多人習慣把 JavaScript include 寫在 <head> 區塊中,這樣一來最大的問題就是 Browser 必須要等到 JavaScript 全部讀完後才會開始顯
【轉】用通俗易懂的話說下hadoop是什麼,能做什麼
轉自http://blog.csdn.net/houbin0912/article/details/72967178hadoop是什麼?(1)Hadoop是一個開源的框架,可編寫和執行分散式應用處理大規模資料,是專為離線和大規模資料分析而設計的,並不適合那種對幾個記錄隨機讀寫
【轉】用opencv使攝像頭在30fps下捕獲1080p的數據
idt apt 壓縮 .com ont blog 設置 幀率 rop 原文:http://blog.sina.com.cn/s/blog_9b493e7b0102xvn6.html opencv可以捕獲攝像頭數據。如果要讀高分辨率和高幀率,可以用如下的設置: captu
【轉】CSS塊級元素和行內元素
http://www.studyofnet.com/news/398.html 本文導讀:HTML中的元素可分為兩種型別:塊級元素和行級元素。這些元素的型別是通過文件型別定義(DTD)來指明。塊級元素:顯示在一塊內,會自動換行,元素會從上到下垂直排列,各自佔一行,如p,ul,
求1到10000的完全數
function wanquanshu() { for(var i=1;i<10000;i++) { var sum=0; for(var j=1;j<i;j++) { if(
求1-1000的所有質數
質數也稱素數,即因子數只有1和其自身,不要和奇數混淆(奇數是不能被2整除的數)! void PrimeNumber() { for (int i = 1; i <= 1000; ++i) { int count = 0, num = 1;//
一個數如果恰好等於它的因子之和(包括1,但不包括這個數本身),這個數就稱為“完數,求1-1000中的完數
/*問題分析:問題中不是要質因數,所以找到的因數後就無需將其從資料中“除掉”。每個因數只記一次如:8的因數為1,2,4而不是1,2,2,2,4*/#include<stdio.h>int main(){int i,k,j,s,a[20];for(i=1;i<
窮舉法求1000內所有完數
題目: 一個數如果恰好等於它的因子之和,這個數就稱為 "完數", 例如6=1+2+3。程式設計找出1000以內的所有完數。 思路: 窮舉法(簡直就是萬能的存在~) 程式碼: package day5; public class&nb