1. 程式人生 > 實用技巧 >POJ 1426 Find The Multiple

POJ 1426 Find The Multiple

題目如下:

在2100年科學家發現了平行宇宙,但是新發現的Earth2的世界中所有數字都是由0和1組成的十進位制數,如果從我們的世界穿越到Earth2,數字將發生一些變化,例如:一個正整數n,將被轉化為n的一個非零的倍數m,這個m應當符合Earth2的數字規則。你可以假定n不大於200且m不多於100位。

提示:本題採用Special Judge,你無需輸出所有符合條件的m,你只需要輸出任一符合條件的m即可。


Input

輸入包含多組資料,每組資料僅一行,只包含一個正整數n,n==0時輸入結束 (1 <= n <= 200).


Output

對於輸入的每組n,都輸出任一符合條件的m。即使有多個符合條件的m,你也只需要輸出一個即可。


Sample Input

2

6

19

0


Sample Output

10

100100100100100100

111111111111111111


解題思路:

這道題我們用dfs/bfs都可以,大體的思路為:迴圈所有需要進行測試的數n,在dfs/bfs中搜索所有隻包含1或0的數字,看這些數字中有沒有為n的倍數,如果有進行打表並結束搜尋,沒有的話繼續搜尋。(在搜尋時注意dfs需要進行剪枝,不然的話會TLS) 將所有測試的數n打表完畢後,當進行測試時,直接查表輸出結果即可!

並且,這道題用bfs會TLE,用dfs則不會,不知道為啥!


程式碼如下(dfs):

#include <iostream>
#include <cstdio>
using namespace std;
int n;
unsigned long long m;
unsigned long long form[202];
void dfs(int i,unsigned long long number,int deep);                 //代表進行深度優先搜尋的函式

void dfs(int i, unsigned long long number, int deep)
{
	unsigned long long temp;
	if (form[i] != 0)                 //如果輸入的數i已經打表成功的話,就不再進行dfs.如果這句話沒有,就會TLS
	{
		return;
	}
	if (deep > 18)                    //經檢視unsigned long long 的最大位數為19位,因此我們要對函式進行剪枝處理。(當遞迴到19層時就退出)
	{
		return;
	}
	temp = number;
	if (temp % i == 0)               //意思詳見bfs程式碼
	{
		form[i] = temp;
		return;
	}
	temp = number * 10;
	dfs(i, temp,deep + 1);
	temp = number * 10 + 1;
	dfs(i, temp,deep + 1);
}

int main()
{
	int i;
	for (i = 1; i <= 200; i++)
	{
		dfs(i,1,0);                        
	}
	while (scanf("%d", &n) != EOF)
	{
		if (n == 0)
		{
			return 0;
		}
		else
		{
			printf("%lld\n", form[n]);
		}
	}
}

程式碼如下(bfs):

#include <iostream>
#include <cstdio>
#include <deque>
using namespace std;
int n;
unsigned long long m;           //由於m的位數非常大,但是經過測試發現,在這道題m的位數在unsigned long long 型別之內
unsigned long long form[202];   //打表(由於輸入的數n範圍為1-200)
deque<unsigned long long> Q;    //代表進行廣度優先搜尋的佇列
void bfs(int i);                //代表進行廣度優先搜尋的函式

void bfs(int i)
{
	unsigned long long temp;    //代表當前正在遍歷的數
	unsigned long long temp1;   //代表將遍歷的數進行計算而得到的數1
	unsigned long long temp2;   //代表將遍歷的數進行計算而得到的數2
	Q.push_back(1);             //代表將起始數1入佇列
	while (!Q.empty())
	{
		temp = Q.front();
		Q.pop_front();
		if (temp % i == 0)      //如果當前遍歷的數(只由1和0構成)是輸入數字的倍數
		{
			form[i] = temp;     //將其寫入表中
			Q.clear();          //清空佇列
			return;             //進行返回
		}
		temp1 = temp * 10;          //讓遍歷的數進行計算後只能有1或0兩個組成
		temp2 = temp * 10 + 1;      //同上
		Q.push_back(temp1);         //入隊
		Q.push_back(temp2);
	}
}
int main()
{
	int i;
	for (i = 1; i <= 200; i++)
	{
		bfs(i);
	}
	while (scanf("%lld", &n) != EOF)
	{
		if (n == 0)
		{
			return 0;
		}
		printf("%lld\n", form[n]);   //查表輸出
	}


}