D e s c r i p t i o n Description Description
给出一个整数 n ( n < 1 0 30 ) n(n<10^{30}) n(n<1030)和 k个变换规则 ( k ≤ 15 ) (k≤15) (k≤15)。
规则:
一位数可变换成另一个一位数:
规则的右部不能为零。
例如:n=234。有规则 ( k = 2 ) (k=2) (k=2):
2
-
>
5
2->5
2->5
3
-
>
6
3->6
3->6
上面的整数234经过变换后可能产生出的整数为(包括原数):
234
234
234
534
534
534
264
264
264
564
564
564
共4 种不同的产生数
问题:
给出一个整数 n 和 k 个规则。
求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
I n p u t Input Input
一个
n
n
n
接下来
n
n
n行,每行一个
x
x
x和
y
y
y,表示
x
x
x可以变化为
y
y
y
O u t p u t Output Output
满足条件的个数
S a m p l e I n p u t Sample Input SampleInput
234 2
2 5
3 6
S a m p l e O u t p u t Sample Output SampleOutput
4
T r a i n Train Train o f of of T h o u g h t Thought Thought
只要可以变化的就连边,然后将每一个数的连边数乘起来就可以了
记得用高精
C o d e Code Code
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
int tot,tt,k,sum[11],ans[31],h[11];
string s; bool b[105];
struct node
{
int now,to;
}w[105];
void ww(int p)
{
sum[tt]++;
b[p]=1;
for (int i=h[p]; i; i=w[i].to)
if (!b[w[i].now])ww(w[i].now);
}//建边
void mul(int p)
{
for (int i=1; i<=30; ++i)
{
ans[i]=ans[i]*p+tot;
tot=ans[i]/10;
ans[i]%=10;
}
}//高精
int main()
{
ans[1]=1;
int x,y,t=0;
tot=0; cin>>s;
scanf("%d",&k);
int len=s.size();
for (int i=1; i<=k; ++i)
{
scanf("%d%d",&x,&y);
w[++t]=(node){y,h[x]}; h[x]=t;
}
for (int i=0; i<=9; ++i)
{
memset(b,0,sizeof(b));
tt=i;
ww(i);
}
for (int i=0; i<len; ++i) mul(sum[s[i]-48]);
int i;
for (i=30; i>0; --i)
if (ans[i]!=0) break;
for (i=i; i>0; --i)
printf("%d",ans[i]);//一位一位输出
return 0;
}