问题
给定你一个数n,让你找出一个能被n整除的由0和1组成的十进制数。
存在多解输出任一个
分析
一看到题就感觉是数论,但是不存在这样的定理。
所以想到了搜索,为了尽可能早的搜到,采取宽度优先搜索。那么如何表示状态和判重呢。如果两个数对n的余数相等,我们可以认为这是一个状态,根据同余定理:
(a*10) mod n=((a mod n)*10 )mod n
(a*10+1)mod n=((a mod n)*10+1)mod n
所以每次只需对余数计算即可,从首位开始搜索,共需搜索n个状态,直到余数等于零。
code
program liukee;
type pig=record
num:int64;
ys:longint;
end;
var
n,x:longint;
q:array[1..500] of pig;
hash:array[0..500] of boolean;
l,r,i,xx:longint;
begin
readln(x);
while x<>0 do
begin
fillchar(hash,sizeof(hash),0);
l:=0;
r:=1;
q[1].num:=1;
q[1].ys:=1 mod x;
hash[q[1].ys]:=true;
while l<r do
begin
inc(l);
xx:=(q[l].ys*10) mod x;
if xx=0 then
begin
writeln(q[l].num*10);
break;
end;
if not hash[xx] then
begin
inc(r);
q[r].num:=q[l].num*10;
q[r].ys:=xx;
hash[xx]:=true;
end;
xx:=(q[l].ys*10+1) mod x;
if xx=0 then
begin
writeln(q[l].num*10+1);
break;
end;
if not hash[xx] then
begin
inc(r);
q[r].num:=q[l].num*10+1;
q[r].ys:=xx;
hash[xx]:=true;
end;
end;
readln(x);
end;
end.
反思
对搜索到的每个状态的存储很关键。如何盘重,及如何由当前状态推知下一状态。