洛谷 P1037 产生数

本文介绍了一道NOIP2002T3的题目,利用高精度运算结合Floyd算法解决整数变换的问题。通过Floyd算法预处理变换规则,使用高精度乘法计算变换后的不同整数的数量。

题目描述

给出一个整数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

 

 

转载于:https://www.cnblogs.com/lipeiyi520/p/10463216.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值