产生数
Description
给出一个整数 n(n<10^30) 和 k
个变换规则(k<=15)。
规则:
一位数可变换成另一个一位数:
规则的右部不能为零。
例如:n=234。有规则(k=2):
2->
5
3-> 6
上面的整数 234
经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共 4
种不同的产生数
问题:
给出一个整数 n 和 k
个规则。
求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
Input
键盘输人,格式为:
n k
x1 y1
x2 y2
... ...
xn
yn
Output
屏幕输出,格式为:
一个整数(满足条件的个数):
Sample Input
234 2
2 5
3 6
Sample Output
4
HINT
有30位数所以要用大数。有个地方值得注意的就是 例如:
input :
123 2
1 2
2 3
output :
6
有6种而不是4种。
123
223
133
323
233
333
一下就可以看出来了。
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 long ans[301],a[301],kind[10];
5 bool flag[10][10];
6 long x,y,k;
7 char ch[101];
8 int main ()
9 {
10 while( scanf ( "%s%d" , ch , &k ) != EOF )
11 {
12 for ( int i = 0 ; i < strlen(ch) ; ++ i )
13 a[i] = ch[i] - '0' ;
14 memset( flag , 0 , sizeof (flag) ) ;
15 for ( int i = 0 ; i < k ; ++ i )
16 {
17 scanf ( "%d%d" , &x , &y ) ;
18 flag[x][y] = true ;
19 }
20 for ( int i = 0 ; i < 10 ; ++ i )
21 flag[i][i] = true ;
22 for ( int i = 0 ; i < 10 ; ++ i )
23 for ( int j = 0 ; j < 10 ; ++ j )
24 if ( i != j )
25 for ( int m = 0 ; m < 10 ; ++ m )
26 if ( j != m && i != m )
27 flag[j][m] = ( flag[j][m] || (flag[j][i] && flag[i][m]) ) ;
28 memset ( kind , 0 , sizeof (kind) ) ;
29 for ( int i = 0 ; i < 10 ; ++ i )
30 for ( int j = 0 ; j < 10 ; ++ j )
31 kind[i] += flag[i][j] ;
32 memset( ans , 0 , sizeof (ans) ) ;
33 ans[0] = 1 ;
34 for ( int i = 0 ; i < strlen (ch) ; ++ i )
35 {
36 for ( int j = 0 ; j <= 30 ; ++ j )
37 ans[j] = ans[j]*kind[a[i]] ;
38 for ( int j = 0 ; j <= 30 ; ++ j )
39 {
40 if ( ans[j] > 9 )
41 {
42 ans[j+1] += ans[j]/10 ;
43 ans[j] %= 10 ;
44 }
45 }
46 }
47 int pos = 30 ;
48 while ( ans[pos] == 0 ) pos -- ;
49 for ( int i = pos ; i >= 0 ; -- i )
50 printf ( "%d" , ans[i] ) ;
51 puts("") ;
52 }
53 // system( "pause" ) ;
54 return 0 ;
55 }
浙公网安备 33010602011771号