程式設計之美 2 8 找符合條件的整數

2021-09-08 02:09:52 字數 1804 閱讀 5623

1. 簡述

任意給定乙個正整數n,求乙個最小的正整數m(m>1),使得n*m的十進位制表示形式裡只含有1和0。

比如n=99時,m=1 122 334 455 667 789,n * m=111 111 111 111 111 111。

2. 思路

實際上兩個思路,乙個就是給n,遍歷m,判斷n*m是否滿足條件的數值;另乙個就是給n,遍歷滿足條件的數值,判斷數值能否被n整除。根據樣例資料發現,n=99時,第乙個方法的複雜度為:m=1 122 334 455 667 789,第二個方法的複雜度為2^15=32 * 1024。即由0和1組成的數值實際上是十分稀疏的,從這邊遍歷更快。這一點與程式設計之美上面3.2節中的**號碼和英文單詞對應很類似,即**號碼的組合是非常巨大的,但是英文單詞是很有限的。

在遍歷只有0或者只有1的數值的過程中,假設目標結果有k位,那麼最多需要遍歷2^k個數字,實際上還可以進一步簡化,比如對於123,123 = 100 + 23即123%n=100%n + 23%n。假設當前已經計算了個位數和十位數的情況,那麼可以保持個位數和十位數對n的那些可能餘數,對於百位數對n的餘數,必然在(100%n+前面計算過的餘數)%n的範圍內,如果有新的餘數產生,更新餘數即可。儲存餘數的時候,記錄該餘數的最小數值即可。這樣假設目標結果有k位,那麼計算複雜度就是k(n-1)。

3. **

#include

using

namespace std;

int find_m(int n)

//高位數值 + 低位正整數的情況

for(int i=1; i//

遍歷每個可能的餘數

if(a[i] == -1)

continue;

int new_x = (x + i) % n; //

計算出的餘數

if(a[new_x] == -1 && b[new_x] == -1) //

if

}//if

}//for factor *= 10;

for(int i=0; iif(a[i]==-1 && b[i]!=-1)

}}//

while

int result = b[0];

delete a;

delete b;

return result;

}int main()

system("

pause

");return

0;}

注意:**中之所以用了兩個餘數陣列,是為了計算出高位的所有的新的餘數,然後一起儲存,如果乙個乙個的計算,那麼高位會受到自身的影響。比如:假設當前計算百位,假設101被儲存在a[7],當前計算到a[2],那麼在計算100+a[7]的時候,實際上算的數值就是100+101=201是非法字元,因此,每次計算出的要一次性的儲存下去。另外需要注意,對於0每次單獨處理,即10+0,100+0的情況。

結果輸出為:

4. 程式設計之美的**

上面的**是看了基本想法寫的,然後又看了下書上的**,發現還是書上的精髓一些,書上**更優的地方有如下幾個:第一,如果n*m數字很大,int存不下的,書上用佇列記錄數值中1的位置,比如對於1,記錄0,對於1110011,記錄01456即可。第二,每個迴圈節,如果沒有新的餘數出現,說明永遠找不到滿足條件的m。這個怎麼證明,還沒太想清楚。此外,書中**也考慮了對高位+0和高位+低位兩種情況,以及高位一次性儲存的問題,不過書中**更優雅一些。

5. 參考

程式設計之美,2.8節,找符合條件的整數

程式設計之美2 8 找符合條件的整數

問題 任意給定乙個正整數n,求乙個最小的正整數m m 1 使得n m的十進位制表示形式裡只含有1和0。解法 由於沒有直接的數學方法能幫我們直接得到m的值,所以我們只能進行搜尋。由於相對m,乘積n m具有明顯的特徵,需要搜尋的空間要小很多,所以我們對乘積n m進行搜尋。如果n m的結果有k位,則要迴圈...

程式設計之美2 8 找符合條件的整數

這個題目是,給定乙個整數 n,需要尋找另外乙個整數 m,使得 n m 得到的結果十進位制表示中只存在1和0兩個數字。首先看到這個題目,第一思想肯定是 使 m 1,並依此遞增 m 的值,直到 n m 獲得想要的效果,但是,如果 n 很大呢,那麼計算量也是很大的,所以,我們需要尋求更好的解決辦法。書中提...

程式設計之美2 8 找符合條件的整數

書上面講的很好,程式也寫得很巧妙。最主要的一句話 只需要將10k n的結果與餘數資訊陣列裡非空的元素相加,再去模n,看看會不會出現新的餘數。include include using namespace std vectorfind number int n bigint 1 push back 0...