第三部分 数据结构 -- 第二章 队列--1361:产生数(Produce)

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;
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章