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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

麦森数(洛谷P1045题题解,Java语言描述)

發(fā)布時間:2025/3/15 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 麦森数(洛谷P1045题题解,Java语言描述) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目要求

題目鏈接

分析

這題挺經典的,快速冪取模算法,如果求出大數(shù)再取模就可能T掉。

之前有篇文章寫了這個算法:《快速冪算法詳解&&快速冪取模算法詳解》

既然是Java,那就要使用出Java的特點!BigInteger還在呢,都不必手寫快速冪。
記住,哪怕是使用快速冪的pow再mod也會炸,所以使用modPow(),直接把模求出來。

你可能會懷疑,(2P?1)mod(10500)(2^{P}-1)mod(10^{500})(2P?1)mod(10500)
是的,這個式子可以化為:(2P)mod(2500)?1(2^{P})mod(2^{500})-1(2P)mod(2500)?1,寫成代碼就是:TWO.modPow(p, 10.pow(500)).substract(1)。
注意上面的數(shù)字是代指,其實基本全是BigInteger對象。

你覺得恍然大悟?
其實不對,做個比方:2…00000000,中間有1000個0,末尾500位全是0,那怎么辦,得到的不是0嗎?0-1就是-1??取模得了-1?
對吧,思考要深入!
所以我們的代碼錯了嗎?

也不是,首先要清楚的是,假設先取冪再取模,底數(shù)一定是2的冪次。
我們看一看2的冪次:2、4、8、16、32、64、128、256、512、1024、2048…
規(guī)律就是,末尾一定是2、4、8、6在循環(huán),所以不可能是0啊!
那我們這么做就是對的!

好,解決了求冪取模的問題,接下來是,你直接用了快速冪取模,沒求冪次,怎么得到2P?12^P-12P?1的位數(shù)?
首先我們知道2P?12^P-12P?12P2^P2P有著相同的位數(shù)(因為2的冪次末位不為零,所以2P2^P2P減去1,位數(shù)并不會改變),所以我們可以直接求2P2^P2P的位數(shù)。
我們不妨設2P=k2^P=k2P=k10n10^n10n位數(shù)為(n+1)(n+1)(n+1),只需換底為10,冪次+1即為所求。
2=10lg22=10^{lg2}2=10lg2 => 2P=(10lg2)P=10p?lg2=k2^P=(10^{lg2})^P=10^{p*lg2}=k2P=(10lg2)P=10p?lg2=k
所以位數(shù)就是p?lg2+1p*lg2+1p?lg2+1,代碼表示就是(int)(Math.log10(2)*p)+1

接下來講代碼編寫的注意事項,稍有不注意就會爆炸:

  • BufferedReader一定要用,否則必炸四個點好像是
  • 不要用String去操作,用BigInteger很穩(wěn)
  • 不要直接取模,用快速冪取模
  • 所有的補位和拼接全用StringBuilder
  • 不要分次輸出,盡量一次輸出
  • 連接\n的時候用單引號比較好
  • 洛谷識別ONE但不識別TWO,所以必須換成new BinInteger(“2”)
  • 求BigInteger對象的位數(shù)不能用bitLength(),那是二進制位數(shù);可以使用toString()后的length()來求
  • ……

有一說一,這題用Java寫,操作性蠻強的。

測試數(shù)據(jù)1:
in
756839
out
227832
18288448825429774219846956862417770870640302475247
92828312585598040121588421297674731878093115313182
16753914541797571068392534875840214937021204750378
89055619401647443568291937923950889819022384242323
28767636683196318572845992994357198238764218257600
09234774987448978769799124034384499030364505405943
84275497234460834579807796823701486980464630401353
54915833132974601389482848422119619724789014565809
44396409267168409183491136926492417685905113427201
26927068487680404055813342880902603793328544677887

測試數(shù)據(jù)7:
in
607
out
183
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000531137992816767098689588206552468
62732959311772703192319944413820040355986085224273
91625022652292856688893294862465010153465793376527
07239409519978766587351943831270835393219031728127

AC代碼(Java語言描述)

import static java.math.BigInteger.*;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigInteger;public class Main {public static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String p = reader.readLine();BigInteger num = new BigInteger("2").modPow(new BigInteger(p), new BigInteger("10").pow(500)).subtract(ONE);reader.close();int length = num.toString().length();StringBuilder result = new StringBuilder();if (length < 500) {for (int i = 0; i < 500-length; i++) {result.append('0');}result.append(num);} else {result.append(num);}String str = result.toString();result = new StringBuilder();result.append((int)(Math.log10(2)*Integer.parseInt(p))+1).append('\n');for (int i = 0; i < 10; i++) {result.append(str, i*50, i*50+50).append('\n');}System.out.println(result);} }

總結

以上是生活随笔為你收集整理的麦森数(洛谷P1045题题解,Java语言描述)的全部內容,希望文章能夠幫你解決所遇到的問題。

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