洛谷 P1037 产生数

题目描述

给出一个整数n(n<10^30)k个变换规则(k15)。

规则:

一位数可变换成另一个一位数:

规则的右部不能为零。

例如:n=234。有规则(k=2):

2->5
3->6
上面的整数234经过变换后可能产生出的整数为(包括原数):

234
534
264
564
4 种不同的产生数

问题:

给出一个整数 n 和k 个规则。

求出:

经过任意次的变换(0次或多次),能产生出多少个不同整数。

仅要求输出个数。

输入输出格式

输入格式:

 

键盘输入,格式为:

n k
x1​ y1
x2​ y2
... ...

xyn

 

输出格式:

 

屏幕输出,格式为:

1个整数(满足条件的个数):

 

输入输出样例

输入样例#1: 
234 2
2 5
3 6
输出样例#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

 

 

posted @ 2019-03-02 22:01  Mr^Simon  阅读(613)  评论(0编辑  收藏  举报