1. 程式人生 > >POJ-1426___Find The Multiple——BFS+同餘模定理

POJ-1426___Find The Multiple——BFS+同餘模定理

題目大意:

    給出一個整數nn(1<=n<=200)(1 <= n <= 200)。求出任意一個它的倍數mm,要求mm必須只由十進位制的0'0'1'1'組成

解題思路:

    思考一下,發現只能是0011列舉,如果不放到搜尋裡,可能想不到BFS。     那麼其實我們思考後,只需要列舉每一位模nn判斷是否有餘數,第一位為11,若第iixx,第i+1i+1為就是x×10+0(x×10+0)% n

nx×10+1(x×10+1)% nn兩種情況,用到同餘模定理: ab(a*b) % n=n =a(a%n+bn +b%nn)% n a+b(a+b)% n=n =a(a%n+bn +b%nn)% n

程式碼思路:

    這裡不給BFS程式碼,本人也是看了別人的題解之後感觸良多,這裡用一個迴圈來模擬BFS雙入口,實現過程值得仔細揣摩和思考

核心:取模、聯想搜尋、也能打表~

#include <iostream>
#include <cstdio>
using namespace std;

int mod[524286];  //儲存每次mod n的餘數
				  //由於198的餘數序列是最長的
				  //經過反覆二分驗證,436905是能儲存198餘數序列的最少空間
				  //但POJ肯定又越界測試了...524286是AC的最低下限,不然鐵定RE

int main() {
	int n, i;
	while(scanf("%d", &n), n) {
		mod[1] = 1%n;  //初始化,n倍數的最高位必是1

		for(i=2; mod[i-1]!=0; i++)  //利用同餘模定理,從前一步的餘數mod[i/2]得到下一步的餘數mod[i]
			mod[i] = (mod[i/2]*10 + i%2) % n;
						  	//mod[i/2]*10+i%2模擬了BFS的雙入口搜尋
						  	//當i為偶數時,+0,即取當前位數字為 0。為奇數時,則 +1,即取當前位數字為 1
		i--;
		int pm=0;
		while(i) {
			mod[ pm++ ] = i%2;   //把*10操作轉化為%2操作,逆向求倍數的每一位數字
			i/=2;
		}
		while(pm)
			printf("%d", mod[--pm]);	//倒序輸出
		printf("\n");
		}
	return 0;
}