sicily_1009 Mersenne Composite N

題目

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

One of the world-wide cooperative computing tasks is the "Grand Internet Mersenne Prime Search" -- GIMPS -- striving to find ever-larger prime numbers by examining a particular category of such numbers.
A Mersenne number is defined as a number of the form (2p–1), where p is a prime number -- a number divisible only by one and itself. (A number that can be divided by numbers other than itself and one are called "composite" numbers, and each of these can be uniquely represented by the prime numbers that can be multiplied together to generate the composite number — referred to as its prime factors.)
Initially it looks as though the Mersenne numbers are all primes.

Prime Corresponding Mersenne Number

2 4–1 = 3 -- prime 
3 8–1 = 7 -- prime 
5 32–1 = 31 -- prime 
7 128–1 = 127 -- prime 

If, however, we are having a "Grand Internet" search, that must not be the case.
Where k is an input parameter, compute all the Mersenne composite numbers less than 2k -- where k <= 63 (that is, it will fit in a 64-bit signed integer on the computer). In Java, the "long" data type is a signed 64 bit integer. Under gcc and g++ (C and C++ in the programming contest environment), the "long long" data type is a signed 64 bit integer.

Input

Input is from file a. in. It contains a single number, without leading or trailing blanks, giving the value of k. As promised, k <= 63.

Output

One line per Mersenne composite number giving first the prime factors (in increasing order) separate by asterisks, an equal sign, the Mersenne number itself, an equal sign, and then the explicit statement of the Mersenne number, as shown in the sample output. Use exactly this format. Note that all separating white space fields consist of one blank.

Sample Input

31

Sample Output

23 * 89 = 2047 = ( 2 ^ 11 ) - 1
47 * 178481 = 8388607 = ( 2 ^ 23 ) - 1
233 * 1103 * 2089 = 536870911 = ( 2 ^ 29 ) - 1


題目大意

找出指數(shù)為63或以下的不是素數(shù)的梅森數(shù)。

思路

  1. 有限小個數(shù)答案的問題句旱,效率最高的是枚舉所有可能的答案倦踢,也就是所謂的直接打表九孩。(然而有作弊的嫌疑)
  2. 建立好素數(shù)表兽肤,然后從中篩選。(然而那么大量數(shù)據(jù)的表庸娱,還沒建好都TLE了)
  3. 簡單粗暴地對每個數(shù)進行質因數(shù)分解赃额。(然而一定會TLE)
  4. 只針對符合答案的情況進行計算。(其實這樣子和打表沒有什么區(qū)別)

代碼

直接打表版

網上說算到59就夠了卓舵,是因為$2^{61}-1$是一個梅森素數(shù)南用,這里不用輸出。

// Copyright (c) 2015 HuangJunjie@SYSU(SNO:13331087). All Rights Reserved.
// sicily 1009: http://soj.sysu.edu.cn/1009
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

int main() {
  int max;
  int answer[9] = { 11, 23, 29, 37, 41, 43, 47, 53, 59 };
  long long int factor[10];
  scanf("%d", &max);

  for (int i = 0; i < 9 && answer[i] <= max; i++) {
    switch (answer[i]) {
      case 11:
        printf("23 * 89 = 2047 = ( 2 ^ 11 ) - 1\n");
        break;
      case 23:
        printf("47 * 178481 = 8388607 = ( 2 ^ 23 ) - 1\n");
        break;
      case 29:
        printf("233 * 1103 * 2089 = 536870911 = ( 2 ^ 29 ) - 1\n");
        break;
      case 37:
        printf("223 * 616318177 = 137438953471 = ( 2 ^ 37 ) - 1\n");
        break;
      case 41:
        printf("13367 * 164511353 = 2199023255551 = ( 2 ^ 41 ) - 1\n");
        break;
      case 43:
        printf("431 * 9719 * 2099863 = 8796093022207 = ( 2 ^ 43 ) - 1\n");
        break;
      case 47:
        printf("2351 * 4513 * 13264529 = 140737488355327 = ( 2 ^ 47 ) - 1\n");
        break;
      case 53:
        printf("6361 * 69431 * 20394401 = 9007199254740991 = ( 2 ^ 53 ) - 1\n");
        break;
      case 59:
        printf("179951 * 3203431780337 = 576460752303423487 = ( 2 ^ 59 ) - 1\n");
        break;
    }
  }

  return 0;
}

簡單粗暴版

大概10s以內的代碼, 里面的注釋能夠幫助理清思路。

// Copyright (c) 2015 HuangJunjie@SYSU(SNO:13331087). All Rights Reserved.
// sicily 1009: http://soj.sysu.edu.cn/1009
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

// get all prime numbers that is no more than num.
// @Param num: the max number that we want the primes less than.
// @return: a prime list.
vector<int> getPrime(int num) {
  vector<int> prime;
  prime.push_back(2);
  for (int i = 3; i <= num; i+=2) {
    bool isPrime = true;
    for (int j = 0; j < prime.size(); j++) {
      if (prime[j] * prime[j] > i) break;
      if (i % prime[j] == 0) {
        isPrime = false;
        break;
      }
    }
    if (isPrime) prime.push_back(i);
  }

  return prime;
}

int main() {
  // gets all posible exponents.
  vector<int> exponent = getPrime(63);

  int max;
  vector<long long int> factor;
  scanf("%d", &max);

  // exams the corresponding mersenne number for a exponent.
  // if the mersenne is a composite number, outputs it.
  for (int i = 0; i < exponent.size() && exponent[i] <= max; i++) {
    long long int mersenne = (1LL << exponent[i]) - 1;
    long long int temp = mersenne;

    // counts the factors.
    factor.clear();
    for (long long int j = 3; j*j < temp; j += 2) {
      if (temp%j == 0) {
        factor.push_back(j);
        temp /= j;
      }
    }
    // if @temp is less than @mersenne, which means that mersenne has some
    // factors, and temp is also a prime factor for it doesn't divide any
    // numbers less than its square root.
    if (temp < mersenne) factor.push_back(temp);

    // factors exists means mersenne is composite. outputs it.
    if (!factor.empty()) {
      for (int j = 0; j < factor.size(); j++) {
        if (j) printf(" * ");
        printf("%lld", factor[j]);
      }
      printf(" = %lld = ( 2 ^ %d ) - 1\n", mersenne, exponent[i]);
    }
  }

  return 0;
}

優(yōu)化版

此版本是參考http://www.cnblogs.com/mjc467621163/archive/2011/07/04/2097278.html

只針對符合的結果運算裹虫,可能剩下超級多的時間肿嘲。

// Copyright (c) 2015 HuangJunjie@SYSU(SNO:13331087). All Rights Reserved.
// sicily 1009: http://soj.sysu.edu.cn/1009
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

int main() {
  int max;
  int answer[9] = { 11, 23, 29, 37, 41, 43, 47, 53, 59 };
  long long int factor[10];
  scanf("%d", &max);

  for (int i = 0; i < 9 && answer[i] <= max; i++) {
    long long int mersenne = (1LL << answer[i]) - 1;
    long long int temp = mersenne;

    memset(factor, 0, sizeof(factor));
    
    int count = 0;
    for (long long int j = 3; j*j < temp; j+=2) {
      if (temp%j ==0) {
        factor[count++] = j;
        temp /= j;
      }
    }
    if (temp < mersenne) factor[count++] = temp;

    for (int j = 0; j < count; j++) {
      if (j) printf(" * ");
      printf("%lld", factor[j]);
    }
    printf(" = %lld = ( 2 ^ %d ) - 1\n", mersenne, answer[i]);
  }

  return 0;
}

以上兩個版本都存在不能檢驗重復因式的問題,所以對優(yōu)化版的因子判斷(21-28行)進行小改良

    int count = 0;
    for (long long int j = 3; j*j < temp; j += 2) {
      if (temp%j == 0) {
        while (temp%j == 0) {
          factor[count++] = j;
          temp /= j;
        }
      }
    }
    if (temp < mersenne) factor[count++] = temp;

參考

http://m.blog.csdn.net/blog/zhanweeleee/40949933
http://www.cnblogs.com/mjc467621163/archive/2011/07/04/2097278.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末筑公,一起剝皮案震驚了整個濱河市雳窟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匣屡,老刑警劉巖封救,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捣作,居然都是意外死亡誉结,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門券躁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搓彻,“玉大人,你說我怎么就攤上這事嘱朽。” “怎么了怔接?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵搪泳,是天一觀的道長。 經常有香客問我扼脐,道長岸军,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任瓦侮,我火速辦了婚禮艰赞,結果婚禮上燎字,老公的妹妹穿的比我還像新娘懈叹。我一直安慰自己,他們只是感情好拌屏,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布罚攀。 她就那樣靜靜地躺著党觅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪斋泄。 梳的紋絲不亂的頭發(fā)上杯瞻,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音炫掐,去河邊找鬼魁莉。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的旗唁。 我是一名探鬼主播畦浓,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逆皮!你這毒婦竟也來了宅粥?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤电谣,失蹤者是張志新(化名)和其女友劉穎秽梅,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剿牺,經...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡企垦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了晒来。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钞诡。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖湃崩,靈堂內的尸體忽然破棺而出荧降,到底是詐尸還是另有隱情,我是刑警寧澤攒读,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布朵诫,位于F島的核電站,受9級特大地震影響薄扁,放射性物質發(fā)生泄漏剪返。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一邓梅、第九天 我趴在偏房一處隱蔽的房頂上張望脱盲。 院中可真熱鬧,春花似錦日缨、人聲如沸钱反。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诈铛。三九已至,卻和暖如春墨礁,著一層夾襖步出監(jiān)牢的瞬間幢竹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工恩静, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留焕毫,地道東北人蹲坷。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像邑飒,于是被迫代替她去往敵國和親循签。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,554評論 0 23
  • 昨夜睡夢中又有些抽筋疙咸,只是肌肉作痛县匠,本不想再跑,偷懶一天撒轮,不過還是堅持去跑了乞旦。去的路上見一貓自在的臥于路邊車的車頂...
    goldfish2017閱讀 274評論 0 0
  • 現(xiàn)在的我們都是處于亞健康狀態(tài),沒有一個人敢肯定的說“我沒病”這三個字题山。外表的健康不代表內在的零件已經脫落或衰竭兰粉。 ...
    PXX秘密之地閱讀 282評論 0 0
  • 她總對人說自己最喜歡的點心是湯圓。 在北方他們都管它叫元宵顶瞳,她還是喜歡從小習慣了的名字玖姑。 湯圓和元宵有什么樣的區(qū)別...
    Lain_M閱讀 932評論 7 5
  • 158家已開始2016校招名企列表 互聯(lián)網(35家) 攜程:http://pages.ctrip.com/xyzp...
    丁叮當ss閱讀 849評論 0 2