题目描述
给出一整数n(<=10^30),k个变化规则(如2->3表示2可变成3),问共有几种产生数。
样例输入
234 2
2 5
3 6
样例输出
4
算法讨论
本题的数据已经明确告诉我们不能用搜索,只用求个数的话我们可以采用乘法原理计数,用f数组表示每个数字包括自己可以变化的个数,把n存入一个字符串,那么总数就可以表示为f[st[1]]*f[st[2]]… *f[st[n]]。由于一个数可以直接或间接的转换成另一数,例如:1->2,2->3,那么1其实也可以转换为3,所以我们要将1->3这条路也标记上,具体算法是一个类似于Floyd的传递,下面的程序会体现出来。最后枚举一遍,若i到j为true就将f[i]加1。
var
a:array[0..9,0..9] of boolean;
f:array[0..9] of longint;
i,j,k,n,m,x,y,l:longint;
st,st1:string;
s:real;
begin
readln(st);
l:=length(st);
for i:=l downto 1 do
if st[i]=' '
then begin
st1:=copy(st,i+1,l-i);
delete(st,i,l-i+1);
val(st1,m);
break
end;
for i:=1 to m do
begin
read(x,y);
a[x,y]:=true
end;
for k:=0 to 9 do
for i:=0 to 9 do
for j:=0 to 9 do
a[i,j]:=a[i,j] or (a[i,k] and a[k,j]); //传递
for i:=0 to 9 do
f[i]:=1;
for i:=0 to 9 do
for j:=0 to 9 do
if (a[i,j]) and (i<>j)
then inc(f[i]);
s:=1; l:=length(st);
for i:=1 to l do
begin
val(st[i],n);
s:=s*f[n]
end;
write(s:0:0)
end.
Pixiv ID:31574858