原来我用宽度搜索,结果TLE
#include "iostream" #include "queue" using namespace std; typedef unsigned long long type; queue<type> Q; int chushu; type a, b; void bfs(){ a = 1; Q.push(a); while(!Q.empty()){ b = Q.front(); Q.pop(); int i = 2; while(i--){ type m = b; m = m * 10 + i % 2; if(m % chushu == 0){ //如果可以整除, 那么输出 cout<<m<<endl; return; } Q.push(m); } } } int main(){ while(cin>>chushu && chushu){ while(!Q.empty()) Q.pop(); bfs(); } return 0; }网上说用queue, 就会TLE, 下面两个程序一个用 同余模定理
(a*b)%n = (a%n *b%n)%n
(a+b)%n = (a%n +b%n)%n
下面解析到第一个程序来自http://user.qzone.qq.com/289065406/blog/1303946967
首先说说朴素的不剪枝搜索方法:
我以n=6为例
首先十进制数,开头第一个数字(最高位)一定不能为0,即最高位必为1
设6的 ”01十进制倍数” 为k,那么必有k%6 = 0
现在就是要用BFS求k值
1、先搜索k的最高位,最高位必为1,则此时k=1,但1%6 =1 != 0
因此k=1不是所求,存储余数 1
2、搜索下一位,下一位可能为0,即 k*10+0,此时k=10,那么k%6=4
可能为1,即 k*10+1,此时k=11,那么k%6=5
由于余数均不为0,即k=10与k=11均不是所求
3、继续搜索第三位,此时有四种可能了:
对于k=10,下一位可能为0,即 k*10+0,此时k=100,那么k%6=4
下一位可能为1,即 k*10+1,此时k=101,那么k%6=5
对于k=11,下一位可能为0,即 k*10+0,此时k=110,那么k%6=2
下一位可能为1,即 k*10+1,此时k=111,那么k%6=3
由于余数均不为0,即k=100,k=101,k=110,k=111均不是所求
4、继续搜索第四位,此时有八种可能了:
对于k=100,下一位可能为0,即 k*10+0,此时k=1000,那么k%6=4
下一位可能为1,即 k*10+1,此时k=1001,那么k%6=5
对于k=101,下一位可能为0,即 k*10+0,此时k=1010,那么k%6=2
下一位可能为1,即 k*10+1,此时k=1011,那么k%6=3
对于k=110,下一位可能为0,即 k*10+0,此时k=1100,那么k%6=2
下一位可能为1,即 k*10+1,此时k=1101,那么k%6=3
对于k=111,下一位可能为0,即 k*10+0,此时k=1110,那么k%6=0
下一位可能为1,即 k*10+1,此时k=1111,那么k%6=1
我们发现k=1110时,k%6=0,即1110就是所求的倍数
程序:
//Memory Time //2236K 32MS #include<iostream> using namespace std; int mod[524286]; //保存每次mod n的余数 //由于198的余数序列是最长的 //经过反复二分验证,436905是能存储198余数序列的最少空间 //但POJ肯定又越界测试了...524286是AC的最低下限,不然铁定RE int main(int i) { int n; while(cin>>n) { if(!n) break; 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) cout<<mod[--pm]; //倒序输出 cout<<endl; } return 0; }
#include<iostream> using namespace std; long long a[23213213]; void BFS(int n) { int left = 0;int right = 0; a[right] = 1; right++; while(left<right) { if((a[left]*10%n)) //填0不能整除 { a[right] = a[left]*10; right++; } else //填0后可以整除 { cout<<a[left]*10<<endl; return ; } if((a[left]*10+1)%n) //填1不能整除 { a[right] = a[left]*10+1; right++; } else //填1后可以整除 { cout<<a[left]*10+1<<endl; return; } left++; } } int main() { int n; while(cin>>n&&n) { if(n==1) cout<<1<<endl; else BFS(n); } return 0; }
从他这里还学到了另一个方法:打表, 这个方法的确很聪明
你的程序超时,但是可以得出正常结果, 想这题你就可以先用你的程序得出全部结果然后, 把结果在粘贴一个txt上保存
,然后写一新程序, 把前面的定义为数组。例子:
#include<iostream> using namespace std; int main() { long long a[205] = {0,1,10, 111, 100, 10, 1110, 1001, 1000, 111111111, 10, 11, 11100, 1001, 10010, 1110, 10000, 11101, 1111111110, 11001, 100, 10101, 110, 110101, 111000, 100, 10010, 1111111101, 100100, 1101101, 1110, 111011, 100000, 111111, 111010, 10010, 11111111100, 111, 110010, 10101, 1000, 11111, 101010, 1101101, 1100, 1111111110, 1101010, 10011, 1110000, 1100001, 100, 100011, 100100, 100011, 11111111010, 110, 1001000, 11001, 11011010, 11011111, 11100, 100101, 1110110, 1111011111, 1000000, 10010, 1111110, 1101011, 1110100, 11111001, 10010, 10011, 111111111000, 10001, 1110, 11100, 1100100, 1001, 101010, 11101001, 10000, 1111111101, 111110, 101011, 1010100, 111010, 11011010, 11010111, 11000, 11010101, 1111111110, 1001, 11010100, 10000011, 100110, 110010, 11100000, 11100001, 11000010, 111111111111111111, 100, 101, 1000110, 11100001, 1001000, 101010, 1000110, 110100111, 111111110100, 1111111011, 110, 111, 10010000, 1011011, 110010, 1101010, 110110100, 11111110101, 110111110, 110001101, 111000, 11011, 1001010, 10011100011, 11101100, 1000, 11110111110, 11010011, 10000000, 100100001, 10010, 101001, 11111100, 11101111, 11010110, 11111111010, 11101000, 10001, 111110010, 110110101, 100100, 10011, 100110, 1001, 1111111110000, 11011010, 100010, 1100001, 11100, 110111, 11100, 1110001, 11001000, 11111011011, 10010, 1110110, 1010100, 10101101011, 111010010, 100011, 100000, 11101111, 11111111010, 1010111, 1111100, 1111110, 1010110, 11111011, 10101000, 10111101, 111010, 1111011111, 110110100, 1111111011, 110101110, 100100, 110000, 101110011, 110101010, 11010111, 11111111100, 1001111, 10010, 100101, 110101000, 1110, 100000110, 1001011, 1001100, 1111111100001, 110010, 11101111, 111000000, 11001, 111000010, 101010, 110000100, 1101000101, 1111111111111111110, 111000011, 1000, 10010001, 1010, 11010111, 10001100 }; int n; while(cin>>n&&n) { cout<<a[n]<<endl; } return 0; }