问题描述
给出一个整数n(n<=2000)和k个变换规则(k≤15)。规则:
① 1个数字可以变换成另1个数字;
② 规则中,右边的数字不能为零。
例如:n=234,k=2规则为
2 → 5
3 → 6
上面的整数234经过变换后可能产生出的整数为(包括原数)234,534,264,564共4种不同的产生数。
求经过任意次的变换(0次或多次),能产生出多少个不同的整数。仅要求输出不同整数个数。
【输入格式】
n
k
x1 y1
x2 y2
… …
xn yn
【输出格式】
格式为一个整数(满足条件的整数个数)。
解题
#include <iostream>
using namespace std;
int a[2001], rule[16][3];
bool bz[2001];
int b[2001];
// 转成数字
int to_num(int arr[], int n) {
int rst = 0;
for (int i=0; i<n; i++) {
rst *= 10;
rst += arr[i];
}
return rst;
}
// 转成数组
int to_arr(int num, int arr[]) {
int n = 0;
int temp = num;
while(temp > 0) {
temp = temp / 10;
n++;
}
temp = num;
for (int i=n-1; i>=0; i--) {
arr[i] = temp % 10;
temp = temp / 10;
}
return n;
}
int main(){
//
for (int i=0; i<=2001; i++) {
bz[i] = true;
}
for (int i=0; i<16; i++){
rule[i][1] = -1;
rule[i][2] = -1;
}
int n,k,from, to, num_arr[32], num;
int head=0;
int tail=0;
cin >> n >> k;
for (int i=0; i<k; i++) {
cin >> from >> to;
rule[i][1]=from;
rule[i][2]=to;
}
b[tail] = n;
tail++;
// 如果队列不为空,则继续循环
while(head <= tail) {
num = to_arr(b[head], num_arr);// 转换数为数组,并返回数组长度给num
// 遍历数组中的每一个数,让所有数参与所有变换
for (int i=0; i<num; i++) {
// 遍历所有变换规则
for (int j=0; j<k; j++) {
// 如果该数是变换规则中存在的数,则进行变换
if (rule[j][1] == num_arr[i]) {
// 获取待变换数字
int tempi = num_arr[i];
// 执行变换
num_arr[i] = rule[j][2];
// 转成整型数
int tempint = to_num(num_arr, num);
// 该数之前不存在,则放入队列,队列长度+1
if (bz[tempint]) {
bz[tempint] = false;
b[tail] = tempint;
tail++;
}
// 回溯该数,进行下一个规则的变换。
num_arr[i]=tempi;
}
}
}
// 执行完一个数的变换后,头指针+1,进行下一个数的变换
head++;
}
cout << tail;
}