给出一个整数n(n<10^30)和k个变换规则(k≤15)。
规则:
一位数可变换成另一个一位数:
规则的右部不能为零。
例如:n=234。有规则(k=2):
2->5
3->6
上面的整数234经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共4 种不同的产生数
问题:
给出一个整数 n 和k 个规则。
求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
键盘输入,格式为:
n k
x1? y1
x2? y2
... ...
xn ?yn?
输出格式:
屏幕输出,格式为:
1个整数(满足条件的个数):
4
解题思路:
高精度+Floyd,先用Floyd求每一个数有几种变换可能,再将每一位的可能数相乘,因为数据过大,需要用高精度.
AC代码:
1 #include<iostream> 2 3 using namespace std; 4 5 string n; 6 int k,f[10],num[101]; 7 bool vis[10][10];//vis[i][j] = 1表示i可以变换到j 8 9 void floyd() {//求出所有数是否能变换为其他数 10 for(int p = 0;p <= 9; p++) 11 for(int i = 0;i <= 9; i++) 12 for(int j = 0;j <= 9; j++) 13 vis[i][j] = vis[i][j] || (vis[i][p] && vis[p][j]); 14 } 15 16 int main() 17 { 18 ios::sync_with_stdio(false); 19 cin >> n >> k; 20 while(k--) { 21 int a,b; 22 cin >> a >> b; 23 vis[a][b] = true; 24 } 25 for(int i = 0;i <= 9; i++) vis[i][i] = true;//每个数都可以从自己变到自己 26 floyd(); 27 for(int i = 0;i <= 9; i++) 28 for(int j = 0;j <= 9; j++) 29 if(vis[i][j]) f[i]++;//记录每一个数有几种变换可能 30 int len = 2; 31 num[1] = 1; 32 for(int i = 0;i < (int)n.length(); i++) {//高精度过程 33 for(int j = 1;j <= 100; j++) num[j] *= f[n[i]-‘0‘]; 34 for(int j = 1;j <= 100; j++) { 35 num[j+1] += num[j] / 10; 36 num[j] %= 10; 37 } 38 while(num[len]) len++; 39 } 40 for(int i = len - 1;i >= 1; i--) cout << num[i]; 41 return 0; 42 }
//NOIP普及 2002 T3
原文:https://www.cnblogs.com/lipeiyi520/p/10463216.html