题目大意:
给定一个整数n(1<=n<=200),求一个n的倍数,该倍数的每一位的数字为0或者1,该倍数一定存在,输入该倍数。
解题思路:
非常不好想到用bfs,宽搜在各位数上为0或者1。
1、该倍数的最高为肯定为1
2、对于树形图上的每一层的元素,设为m(0<=m<n),该子数为(m*10+0)%n和(m*10+1)%n
3、以n=6为例:
各节点存储取模后的值
第一层:1
第二层:(1*10+0)%6=4
(1*10+1)%6=5
第二层:(4*10+0)%6=4 //上一层已经出现了该值,该处需要剪枝
(4*10+1)%6=5 //剪枝
(5*10+0)%6=1 //剪枝
(5*10+1)%6=2
第三层:(2*10+0)%6=2 //剪枝
(2*10+1)%6=3
第四层:(3*10+0)%6=0 //到此宽搜结束,不断的向父节点回找路径,知道根节点
代码如下:
#include<stdio.h>
#include<string.h>
int vis[300]; //标记取模后的值是否已经出现过
int head,tail;
int tmp;
struct Num{
int n;
int pre,type; //pre保存父节点在队列中的下标值,type标记操作方法(0或者1)
};
Num num[1000];
void bfs(int n){
head=0,tail=0;
num[tail].n=1;num[tail].type=1;num[tail++].pre=-1;
vis[1]=1;
while(true){
tmp=(num[head].n*10)%n;
if(vis[tmp]==0){
vis[tmp]=1;
num[tail].n=tmp;
num[tail].type=0;
num[tail++].pre=head;
if(tmp==0)
break;
}
tmp=(num[head].n*10+1)%n;
if(vis[tmp]==0){
vis[tmp]=1;
num[tail].n=tmp;
num[tail].type=1;
num[tail++].pre=head;
if(tmp==0)
break;
}
head++;
}
}
int main(){
int n;
while(scanf("%d",&n),n){
memset(vis,0,sizeof(vis));
bfs(n);
tail--;
int mod[400],th=0;
while(num[tail].pre!=-1){
mod[th++]=num[tail].type;
tail=num[tail].pre;
}
printf("1");
for(int i=th-1;i>=0;i--)
printf("%d",mod[i]);
printf("\n");
}
}