日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

输出和为n的所有的连续自然数序列

發布時間:2025/3/19 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 输出和为n的所有的连续自然数序列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

輸出和為n的所有的連續自然數序列

n = 9

?9

?4 5

?2 3 4

?

《編程之美》的題目(2.21只考加法的面試題),去年曾經寫過本題的代碼,后來不知道把代碼放哪里了。按以前的思路,重寫了下代碼,寫完后翻了下書,結果發現與書上要求的還不一樣。

?

假設,拆分成的數列為:m, m+1, … m+k-1

n = (m + m + k - 1) * k / 2? 2*n = (2*m + k - 1) * k

?

顯然就是求2*n的所有因子,最簡單的方法就是暴力搜索:

?

對公式2*n = (2*m + k - 1) * k 進行轉變,可得下面幾種方法:

?

方法一:

?? 2*m + k – 1 = 2 * n / k

??k = 1 開始判斷 k 是否是 2 * n的因子,當 k > 2 * n / k 時終止

?? (由于2*m + k – 1 k奇偶性相反,輸出結果前還要判斷k2 * n / k是否奇偶性相反)

循環次數約為:sqrt(2*n)

?

方法二:

??m = (n – k * (k - 1) / 2) / k > 0

??k = 1 開始判斷 k 是否是(n – k * (k - 1) / 2)的因子,當m <= 0時終止

循環次數約為:sqrt(2*n)

?

上面兩種方法,效率相差不大,并且都不高,對 n = 2^30,這種不能拆分的數,要進行大量的計算。注意到2*m + k – 1 k奇偶性相反,可以先將2 * n的所有質因子2提取出來,假設總共有t2,則 2 * n = 2^t * nnnn為奇數),問題轉為求nn的所有因子,假設nn = a * b (a <= b),由于 2 * m + k – 1 一定大于k,由2 * n = 2^t * a * b可得兩組2*n的兩組因子(2^t * a, b) (a, 2^t * b) 這兩組數中,較小的那個就是k。采用這種方法的好處是,對偶數能極大的減少計算,特別是對n = 2^30,可以不進行任何除法計算。

nn求因子,可以采用上面的方法一和方法二,于是得到方法三和方法四。

?

方法三:

2 * n = 2^t * nn?奇數 nn = i * j?(i?<= j)?? ->?? j = nn / i

i = 1開始(每次遞增2),判斷i是否是nn的因子,當 j > i 時終止。

循環次數約為:sqrt(nn) / 2

?

方法四:

2 * n = 2^t * nn?奇數 nn = i * (i + j)?(j >= 0)?? ->?? j = (nn – i * i) / i?>= 0

i = 1開始(每次遞增2),判斷i是否是(nn – i * i) / i的因子,當 j < 0時終止。

循環次數約為:sqrt(nn) / 2

?

方法五:

既然是求所有的因子,那么最好的方法當然是利用質因子進行組合。

下面的代碼存在一些需要優化的地方,比如存在重復計算、防止編譯器對n / i n % i進行兩次除法計算。如果數不是太大,可以緩存所有的質因子。

另見: 輸出自然數n的所有因子。

(下面的代碼,要將函數參數改為unsigned的話,需要將i=1的情況單獨列出來討論,即可保證計算過程中不會發生溢出。)

?

void output(int beg, int len) { printf("%d-%d\n", beg, beg + len - 1); }

inline void output2(int i, int j) { output((i - j + 1) / 2u, j); }

?

//方法三

void seq3(int n)??????????

{??????????????????????? //2*n = (2*m+k-1)*k?//m, m+1, ... m+k-1

?if (n <= 0) return;?? //?

?unsigned count = 1;??

?while (n % 2u == 0) { n /= 2u; ++count; } //去除質因子2,設f = 2^x???

?for (unsigned i = 1; ;i += 2) { //獲取nn的所有因子 nn = i * j 且 i <= j

??? unsigned j = n / i;

??? if (i > j) break;

??? if (n % i)?continue;

??? output2(j << count, i);?//k=i ?2m+k-1=j*2*f?

??? if (i == j) break;

??? unsigned t = i << count;???

??? if (t > j) output2(t, j);??

??? else output2(j, t);

?}

?printf("\n");

}

?

?

//方法四

void seq4(int n)??????????

{??????????????????????? //2*n = (2*m+k-1)*k?//m, m+1, ... m+k-1

?if (n <= 0) return;?? //?

?unsigned count = 1;??

?while (n % 2u == 0) { n /= 2u; ++count; } //去除質因子2,設f = 2^x

?n -= 1 * 1;???

?for (unsigned i = 1; n >= 0; n -= 4 * i + 4, i += 2) { //獲取nn的所有因子

??? if (n % i == 0) {???? // nn = (i+a)*i?-> a = (nn - i * i) / i

????? unsigned j = n / i + i;

????? output2(j << count, i);?//k=i 2m+k-1=j*2*f ??

????? if (i == j) continue;

????? unsigned t = i << count;?????

????? if (t > j) output2(t, j);??

????? else output2(j, t);

??? }??

?}

?printf("\n");

}

?

?

//方法五

unsigned gn = 0;?//值為 2 * n

static void factor(unsigned n, unsigned k = 1, unsigned beg = 3)

{

?assert(n & 1);

?assert(beg & 1);

?if (n == 1) {

??? unsigned t = ::gn / k;

??? if (t > k) output2(t, k);

??? else output2(k, t);

??? return;

?}

?assert(n >= beg);

?

?for (unsigned i = beg, count = 0; ;i += 2) {

??? //if (n % i) {

??? //?if (n / i >= i) continue;

??? //?factor(1, k, n);?? // n是質數

??? //?factor(1, k * n, n);

??? //?return;?

??? //}

??? if (i > n / i) {

????? factor(1, k);?? // n是質數,

????? factor(1, k * n);

????? return;???????

??? }

??? if (n % i) continue;

???

??? ++count;

??? n /= i;

??? while (n % i == 0) { ++count; n /= i; }

??? for (unsigned j = 0, f = k; j <= count; ++j, f *= i)?

????? factor(n, f, i + 2);

??? return;??

?}

}

?

void seq(int n)??????????

{?? ?????????????????????//2*n = (2*m+k-1)*k?//m, m+1, ... m+k-1

?if (n <= 0) return;

?::gn = n * 2u;

?while (n % 2u == 0) { n /= 2u;} //去除質因子2

?factor(n);

?printf("\n");

}

?

?

?

轉載于:https://www.cnblogs.com/flyinghearts/archive/2011/03/22/1992003.html

總結

以上是生活随笔為你收集整理的输出和为n的所有的连续自然数序列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。