题目链接:https://www.cometoj.com/problem/0168
解题思路:
计算出每个数字的可变化次数,其中特别注意如果1 -> 2, 2 -> 3,那么1 -> 3同样成立,于是可用有向图来表示各个顶点之间的连接情况,在采用dfs来求出每一个顶点的可达顶点数。
遍历n每个顶点的数相乘(乘法原理)注意数很大,要用高精度。
实现代码:
#include <iostream> //[2002普及组-C]产生数
#include <algorithm>
#include <cstring>
using namespace std;
int num[10], cnt; //计数
int m[10][10]; //图
bool Vis[10];
int number[1000], len; //大整数
void dfs(int x) //dfs找出有向边图的顶点x所有能到达的顶点
{
Vis[x] = true;
for (int i = 0; i < 10; i++)
if(m[x][i] && !Vis[i])
{
cnt++;
dfs(i);
}
}
void mul(int number[], int k) //高精度乘法
{
int add = 0;
for (int i = 0; i < len; i++)
{
int t = number[i] * k + add;
number[i] = t % 10;
add = t / 10;
}
while (add)
{
number[len++] = add % 10;
add /= 10;
}
}
int main()
{
string n;
int k, x, y;
number[0] = 1, len = 1;
cin >> n >> k;
for (int i = 0; i < k; i++)
{
cin >> x >> y;
m[x][y] = 1;
}
for (int i = 0; i < 10; i++) //找出所有可达顶点数
{
cnt = 0;
memset(Vis, false, sizeof(Vis));
dfs(i);
num[i] = cnt; //记录每个顶点的可达顶点数
}
for (int i = 0; i < n.size(); i++)
if(num[n[i] - '0'])
mul(number, num[n[i] - '0'] + 1); //sum *= num[n[i] - '0'] + 1;
for (int i = len - 1; i >= 0; i--)
cout << number[i];
cout << endl;
system("pause");
return 0;
}