题目描述
给出一个整数 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=234。有规则(k=2):
2-> 5
3-> 6
上面的整数 234 经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共 4 种不同的产生数
问题:
给出一个整数 n 和 k 个规则。
求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
输入
n k
x1 y1
x2 y2
... ...
xn yn
x1 y1
x2 y2
... ...
xn yn
输出
一个整数(满足条件的个数)
样例输入
234 2 2 5 3 6
样例输出
4
思路:将规则描述成为一个完整的邻接矩阵,找各个节点的邻接节点数+1(包括自身),将所有点的邻接节点数最后相乘既是最后答案。
import java.math.BigInteger;
import java.util.Scanner;
public class 产生数 {
/**
* @param args
*/
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int k=sc.nextInt();
//将输入的数字转化为字符数组
char chn[]=String.valueOf(n).toCharArray();
int map[][]=new int[10][10];
//录入规则,a->b
for (int i = 1; i <=k; i++) {
int a=sc.nextInt();
int b=sc.nextInt();
map[a][b]=1;
}
//根据规则,更新每个数字能链接到的节点
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map.length; j++) {
for (int div = 0; div < map.length; div++) {
if(div!=i && div!=j && i!=j){
if(map[i][div]==1 && map[div][j]==1){
map[i][j]=1;
}
}
}
}
}
BigInteger sum=BigInteger.ONE;//初始化“总的可能情况数”
for (int i = 0; i < chn.length; i++) {
int x=chn[i]-'0';//转化成int的节点下标
int count=1;//初始化为1是因为,最后可能的数中包含自身,所以自身也是一种情况
for (int j = 0; j < map.length; j++) {
if(map[x][j]==1){//符合规则可以交换(走通)
count+=map[x][j];//计算每一位数字最多能变为几种数字
}
}
String ss=String.valueOf(count);
sum=sum.multiply(new BigInteger(ss));
}
System.out.println(sum);
}
}