原来我用宽度搜索,结果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;
}
下面的程序不用queue,采用同样的机理实现了BFS, 非常值得学习,来自http://hi.baidu.com/cibiluozu/item/b80a1b14a984ee5ee75e0656
#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;
}