1361:产生数(Produce)
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 3296 通过数: 1420
【题目描述】
给出一个整数n(n≤2000)和k个变换规则(k≤15)。规则:
① 1个数字可以变换成另1个数字;
② 规则中,右边的数字不能为零。
例如:n=234,k=2规则为
2 → 5
3 → 6
上面的整数234经过变换后可能产生出的整数为(包括原数)234,534,264,564共4种不同的产生数。
求经过任意次的变换(0次或多次),能产生出多少个不同的整数。仅要求输出不同整数个数。
【输入】
nkx1x2…xny1y2…yn
【输出】
格式为一个整数(满足条件的整数个数)。
【输入样例】
234
2
2 5
3 6
【输出样例】
4
思路:1、我们只要知道原数num的每一位数有多少种变换,然后每一位的可能的变换数相乘即可。
2、所以问题就拆分为一个一位数在k个变换规则的约束下有多少种变换,题例 2->4 ,3->5。也就是234这个数的第一位2可以变成4,这一位存在两种可能结果,同理第二位3也存在两种可能结果。所以结果就是4=2*2。
3、2->3,3->4,3->5这就要用到队列了,所以可以考虑BFS搜索来进行操作。
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 20; // 题目种的变换规则<=15
char num[5]; // 题目种的数<2000最多也就4位数,
int k;
int f[N],t[N]; // 存放变换规则
bool vis[N];// 用来当作标记,访问过的数不能再访问了
ll ans = 1;
ll bfs(){
int lena = strlen(num);
queue <int> q;
for(int i = 0; i < lena; i++)// 对num的每一位进行bfs
{
int cur = num[i] -'0';
q.push(cur);
memset(vis,1,sizeof(vis));
int tmp = 1;
while(!q.empty()){
int top = q.front();
for(int j = 0 ; j < k; j++){
if(top == f[j] && vis[t[j]]){
tmp++;
q.push(t[j]);
vis[f[j]] = 0; // 2->5 5->2
vis[t[j]] = 0; // 2->5 3->5
}
}
q.pop();
}
ans *= tmp;
}
return ans;
}
int main(){
cin >> num;
cin >> k;
for(int i = 0; i < k; i++)
cin >> f[i] >> t[i];
cout << bfs();
return 0;
}