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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[算法] 两个质数的乘积是707829217,求解该质数

發(fā)布時間:2023/12/8 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [算法] 两个质数的乘积是707829217,求解该质数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

記錄一次有趣的算法題。

土生土長的北京妞兒,在胡同里長大,房不多,就一個四合院和近郊的別墅。不算美如天仙但還算標(biāo)致,在清華讀的經(jīng)管,現(xiàn)在在做基金經(jīng)理(不想被人肉,就不暴露單位啦) ,個人擅長基本面分析,價值投資。現(xiàn)在只想找個聰明靠譜的IT男。硬性要求是年齡,不要超過88年,還有不要特別矮或胖。我對智商的要求比較高,下面就出個題測試下。

我的微信ID是大寫字母NY后面跟著兩個質(zhì)數(shù),大的在前,小的在后,乘積是707829217,可直接搜索添加,另外還有個附加題目,在剛剛微信ID的數(shù)字中,從1開始到這個數(shù)字的奇數(shù)序列里,一共出現(xiàn)了多少個3,如果私信我正確的答案,我將直接邀你見面!期待緣分降臨~

問題1 求解微信號

// 兩個質(zhì)數(shù)的乘積是707829217,求質(zhì)數(shù)int num = 707829217;int i = 1;while (i <= num) {i += 2;if (num % i == 0) {System.out.println("發(fā)現(xiàn): " + num + " / " + i + " = " + (num / i));}}

打印結(jié)果:

發(fā)現(xiàn): 707829217 / 8171 = 86627 發(fā)現(xiàn): 707829217 / 86627 = 8171 發(fā)現(xiàn): 707829217 / 707829217 = 1Process finished with exit code 0

所以我們得到第一問的答案:NY866278171

問題2 求解奇數(shù)序列中,3出現(xiàn)的次數(shù)

我們看到這個數(shù)值866278171,為8億多,去掉偶數(shù),只看奇數(shù),也有4億多。

問這4億個數(shù)中3出現(xiàn)了多少次,這個問題有點費解。

方式一 暴力破解

所謂暴力破解,就是遍歷每一個數(shù)值,統(tǒng)計3出現(xiàn)的次數(shù)。下面的各個版本僅供參考:

該方案耗時:2m 52s 139ms

// 奇數(shù)序列中,一共出現(xiàn)了多少次3int number = 866278171;int sum = 0;for (int i = 1; i <= number; i = i + 2) {sum += String.valueOf(i).replace("3", "_#_").split("#").length - 1;}// 總數(shù): 441684627System.out.println("總數(shù): " + sum);

該方案耗時:1m 41s 259ms

// 奇數(shù)序列中,一共出現(xiàn)了多少次3int number = 866278171;int sum = 0;for (int i = 1; i <= number; i = i + 2) {String str = String.valueOf(i);if (str.contains("3")) {sum += str.length() - str.replace("3", "").length();}}// 總數(shù): 441684627System.out.println("總數(shù): " + sum);

該方案耗時:22s 942ms

// 奇數(shù)序列中,一共出現(xiàn)了多少次3int number = 866278171;int sum = 0;for (int i = 1; i <= number; i = i + 2) {String str = String.valueOf(i);for (int j = 0; j < str.length(); j++) {if (str.charAt(j) == '3') {sum++;}}}// 總數(shù): 441684627System.out.println("總數(shù): " + sum);

該方案耗時:6s 669ms

// 奇數(shù)序列中,一共出現(xiàn)了多少次3int number = 866278171;int sum = 0;for (int i = 1; i <= number; i = i + 2) {int k = i;while (k > 1) {if (k % 10 == 3) {sum++;}k /= 10;}}// 總數(shù): 441684627System.out.println("總數(shù): " + sum);

我們看到,走了好多的彎路,String類中的replace和contains都是重量級方法。當(dāng)我們使用有限次數(shù)時,并不會感覺到慢。但是當(dāng)我們需要重復(fù)執(zhí)行上億次時,就很慢了。

方式二 公式法

規(guī)律總結(jié)

  • 對于1位數(shù)
3只出現(xiàn)1次。
  • 對于2位數(shù):
3出現(xiàn)在個位數(shù),十位數(shù)可以任意0-9,有10種。33暫時算一次 3出現(xiàn)在十位數(shù),個位數(shù)可以任意0-9,有10種,33暫時算一次,加上上一次的補齊 所以,對于任意兩位數(shù),3出現(xiàn)了20次。
  • 對于3位數(shù):
3出現(xiàn)在個位數(shù),十位數(shù)、百位數(shù) 可以任意00-99,有100種。 x33、3x3、333暫時算一次 3出現(xiàn)在十位數(shù),個位數(shù)、百位數(shù) 可以任意00-99,有100種。 x33、33x、333暫時算一次 3出現(xiàn)在百位數(shù),個位數(shù)、十位數(shù) 可以任意00-99,有100種。 3x3、33x、333暫時算一次 少算的,都補齊了,所以,對于任意3位數(shù),3出現(xiàn)了300次。
  • 對于4位數(shù):
3出現(xiàn)在個位數(shù),十位數(shù)、百位數(shù)、千位數(shù) 可以任意000-999,有1000種。 xx33、x3x3、3xx3、x333、33x3、3x33、3333暫時算一次 3出現(xiàn)在十位數(shù),個位數(shù)、百位數(shù)、千位數(shù) 可以任意000-999,有1000種。 xx33、x33x、3x3x、x333、3x33、333x、3333暫時算一次 3出現(xiàn)在百位數(shù),個位數(shù)、十位數(shù)、千位數(shù) 可以任意000-999,有1000種。 x3x3、x33x、33xx、x333、33x3、333x、3333暫時算一次 3出現(xiàn)在千位數(shù),個位數(shù)、十位數(shù)、百位數(shù) 可以任意000-999,有1000種。 3xx3、3x3x、33xx、3x33、33x3、333x、3333暫時算一次 少算的,都補齊了,所以,對于任意4位數(shù),3出現(xiàn)了4000次。

好像有點規(guī)律了。。

對于任意N位數(shù),3出現(xiàn)的次數(shù)為 n * 10^(n-1)

翻譯成代碼:

/*** 任意N位數(shù),3出現(xiàn)的次數(shù)*/public double anyN(int n) {if (n < 1)return 0;return n * Math.pow(10, n - 1);}

問題來了,對于一個有限度的N位數(shù),3出現(xiàn)了多少次?

比如: 0 ~ 2918,3出現(xiàn)了多少次?拆分下: 0 ~ 2000區(qū)間段, 可以理解為2個1000,也就是2個任意3位數(shù),所以 :2 * 300 + 0 (對于任意3位數(shù)3出現(xiàn)的次數(shù)為300,不包含3000~3999 整個以3開頭的千位數(shù)) 2000 ~ 2900區(qū)間段, 可以理解為9個100,也就是9個任意2位數(shù),所以:9 * 20 + 100( 任意2位數(shù)3出現(xiàn)的次數(shù)為20,包含300-399 整個以3開頭的百位數(shù)) 2900 ~ 2910區(qū)間段, 可以理解為1個10,也就是1個任意1位數(shù),所以:1 * 1 + 0( 任意1位數(shù)3出現(xiàn)的次數(shù)為1,不包含30-39 整個以3開頭的十位數(shù)) 2910 ~ 2918區(qū)間段, 只看個位數(shù),0 ~ 8,包含一個3,所以: 1 綜合起來就是: (2 * 300 + 0)+(9 * 20 + 100) + (1 * 1 + 0) + (1)= 600+280+1+1 = 882

我們拆開翻譯,

  • 步驟1

對于0 ~ n * 10^w 的數(shù),3出現(xiàn)了多少次。
比如0~100,0~4000,0~800000000

/*** 計算一個 [ 0 , n*10^w ) 的數(shù)中,3出現(xiàn)的次數(shù)* <p>* e.g: 4000 n = 4 , w = 3** @param n 數(shù)值* @param w 0的個數(shù)* @return*/public int count3(int n, int w) {// n * 10^(w-1) + 10^wdouble sum = n * anyN(w);if (n > 3) {sum += Math.pow(10, w);}return (int) sum;}
  • 步驟2

對于任意0 ~ N, 3出現(xiàn)了多少次

/*** 計算0~N的數(shù)中,3出現(xiàn)的次數(shù)*/public int anyNumCount3(int anyN) {double sum = 0;int number = anyN;int count0 = 0;while (number > 1) {int n = number % 10;sum += count3(n, count0);if (n == 3) {// 如果該位為3,需要將低位數(shù)再加一遍。// 比如 389,[300,389]共89+1=90個sum += (anyN % Math.pow(10, count0)) + 1;}number /= 10;count0++;}return (int) sum;}

該方案耗時:1ms ?

至此,我們通過找規(guī)律,發(fā)現(xiàn)了對于[0~N]中3出現(xiàn)的次數(shù)的公式。

只看奇數(shù)序列

針對本題的只看奇數(shù)序列,我們總結(jié)下規(guī)律:

奇數(shù),也就是限定了個位數(shù)只能是1、3、5、7、9共5種選擇,而更高位可以是0-9共十種選擇。

對于任意N位奇數(shù)

  • 對于1位數(shù)
3只出現(xiàn)1次。
  • 對于2位數(shù):
3出現(xiàn)在個位數(shù),十位數(shù)可以任意0-9,有10種。33暫時算一次 3出現(xiàn)在十位數(shù),個位數(shù)可以是13579,有5種,33暫時算一次,加上上一次的補齊 所以,對于任意兩位數(shù),3出現(xiàn)了15次。
  • 對于3位數(shù):
3出現(xiàn)在個位數(shù),十位數(shù)0-9、百位數(shù)0-9,有10*10=100種。 x33、3x3、333暫時算一次 3出現(xiàn)在十位數(shù),百位數(shù)0-9,個位13579,有10*5=50種。 x33、33x、333暫時算一次 3出現(xiàn)在百位數(shù),十位數(shù)0-9,個位13579,有10*5=50種。 3x3、33x、333暫時算一次 少算的,都補齊了,所以,對于任意3位數(shù),3出現(xiàn)了200次。
  • 對于4位數(shù):
3出現(xiàn)在個位數(shù),十、百、千位數(shù) 可以任意0-9,有1000種。 xx33、x3x3、3xx3、x333、33x3、3x33、3333暫時算一次 3出現(xiàn)在十位數(shù),個位13579、百、千位數(shù) 可以任意0-9,有500種。 xx33、x33x、3x3x、x333、3x33、333x、3333暫時算一次 3出現(xiàn)在百位數(shù),個位13579、十、千位數(shù) 可以任意0-9,有500種。 x3x3、x33x、33xx、x333、33x3、333x、3333暫時算一次 3出現(xiàn)在千位數(shù),個位13579、十、百位數(shù) 可以任意0-9,有500種。 3xx3、3x3x、33xx、3x33、33x3、333x、3333暫時算一次 少算的,都補齊了,所以,對于任意4位數(shù),3出現(xiàn)了2500次。

規(guī)律:對于任意N位數(shù),只看奇數(shù),3出現(xiàn)的次數(shù)為1*10^(n-1) + (n-1)*5*10^(n-2)

翻譯成代碼:

/*** 任意N位奇數(shù),3出現(xiàn)的次數(shù)* e.g: 9999 n = 4*/public int anySingleN(int n) {// 1*10^3 + 3*5*10^2if (n < 1) return 0;double sum = Math.pow(10, n - 1);if (n >= 2) {sum += (n - 1) * 5 * Math.pow(10, n - 2);}return (int) sum;}

對于有限制的N位奇數(shù),3出現(xiàn)的次數(shù)

  • 比如:4000以內(nèi)的奇數(shù)

4個任意三位奇數(shù) + 3開頭的,任意4位奇數(shù)。即4*anySingleN(3) + 10*10*5

翻譯成代碼:

/*** 計算一個 [ 0 , n*10^w ) 的奇數(shù)中,3出現(xiàn)的次數(shù)* <p>* e.g: 4000 n = 4 , w = 3** @param n 數(shù)值* @param w 0的個數(shù)* @return*/public int countSingle3(int n, int w) {// 4 * anySingleN(3) + 5*10^2if (w < 1)// 個位數(shù)return (n >= 3) ? 1 : 0;double sum = n * anySingleN(w);if (n > 3) {sum += 5 * Math.pow(10, w - 1);}return (int) sum;}
  • 對于0~N的任意奇數(shù)中,3出現(xiàn)的次數(shù)
/*** 計算0~N的奇數(shù)數(shù)中,3出現(xiàn)的次數(shù)*/public int anySingleNumCount3(int anyN) {int sum = 0;int number = anyN;int count0 = 0;while (number > 0) {int n = number % 10;sum += countSingle3(n, count0);if (n == 3) {// 如果該位為3,需要將低位奇數(shù)再加一遍// 比如 389,[300-389]共(89+1)/2 = 50個sum += (anyN % Math.pow(10, count0) + 1) / 2;}number /= 10;count0++;}return (int) sum;}

該方案耗時:1ms ?

至此,我們通過找規(guī)律,發(fā)現(xiàn)了對于[0,N]奇數(shù)序列中3出現(xiàn)的次數(shù)的公式。

總結(jié)

我們通過 方案一 暴力破解方案二 公式法 來解決了這個問題。

速度對比那就更不用說了

總結(jié)

以上是生活随笔為你收集整理的[算法] 两个质数的乘积是707829217,求解该质数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。