標籤:acm poj 搜尋 bfs
Find The Multiple
| Time Limit: 1000MS |
|
Memory Limit: 10000K |
| Total Submissions: 18012 |
|
Accepted: 7297 |
|
Special Judge |
Description
Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.
Input
The input file may contain multiple test cases. Each line contains a value of n (1 <= n <= 200). A line containing a zero terminates the input.
Output
For each value of n in the input print a line containing the corresponding value of m. The decimal representation of m must not contain more than 100 digits. If there are multiple solutions for a given value of n, any one of them is acceptable.
Sample Input
26190
Sample Output
10100100100100100100111111111111111111
Source
Dhaka 2002
開始做這道題的時候半天沒有讀懂題意,範例資料是嚇人的,把一個單詞理解錯誤,multiple在這裡是倍數的意思,這個題目就是要求我們求出給定的一個數的一個由0,1組成的倍數,100位也是嚇人的。開始看那個範例,完全不好理解啊,看了半天沒有理解題意,也想不到要用bfs來做,看了別人的一點提示就清晰啦;就用一個隊列來類比運算的過程,如果可以整除就直接輸出,不能整除把他*10,和*10+1入隊;因為都是0,1組成的倍數,所以組成直接*10,或者是*10+1;下面是用stl寫的,第一次用stl寫,有點水,用stl在poj上c++過不了,g++才過的;
#include <iostream>#include <queue>#include <cstdio>using namespace std;void bfs(int n){ queue<__int64>q;//這裡後面的資料可能會有大的,所以用個64位的就夠了 q.push(1); while(!q.empty()) { __int64 x; x=q.front(); q.pop(); if(x%n==0)//可以整除就直接輸出 { printf("%I64d\n",x); return ; } q.push(x*10);//把x的10的倍數入隊; q.push(x*10+1); }}int main(){ int n; while(scanf("%d",&n)&&n) { bfs(n); } return 0;}
自己用數組類比隊列寫了一下;貌似效率比stl好了一些;基本的思想都是一樣的;
#include <cstdio>#include <cstring>long long q[2000000];void bfs(int n){ int front=0; int rear=0; q[front]=1; rear++; long long temp; while(rear>front) { temp=q[front]; if(temp%n==0) { break; } temp*=10; q[rear]=temp; rear++; q[rear]=temp+1; rear++; front++; } printf("%lld\n",temp);}int main(){ int n; while(scanf("%d",&n)&&n) { bfs(n); } return 0;}
在網上還看到了大神的代碼用了同餘模數定理,還是有點沒看懂,還有的直接用滿二叉樹類比的隊列;http://blog.csdn.net/lyy289065406/article/details/6647917 (用的同餘模數定理)
(a*b)%n = (a%n *b%n)%n
(a+b)%n = (a%n +b%n)%n
看到其他大神對這道的思路:
再貼一段pl大牛關於此題的分析思路,以學習:
要m整除n,那麼可以用對n的餘數來表示當前的狀態。
搜到一個餘數為0的狀態就可以了。
直接bfs出去。
如果當前的餘數是r,添在當前答案後面的數為,k
那麼新的餘數,也就是新的狀態為:
( r * 10 + k ) % n 。
這樣最多200個狀態,判重一下,可以很快出解。
大牛的代碼:
#include<iostream>using namespace std;int a[524300],i,n;int main(){while(cin>>n){ if (!n) break; i=1; a[1]=1%n; while(a[i]){i++; a[i]=(a[i/2]*10+i%2)%n;} n=0; while(i){a[n++]=i%2;i>>=1;} while(n--) cout<<a[n]; cout<<endl;}return 0;}這原來也是bfs,直接用一個滿二叉樹實現(左兒子是0,右兒子是1);
還是要多學習大神們的代碼~