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;
}