[蓝桥杯][算法提高VIP]产生数

时间限制: 1Sec 内存限制: 128MB 提交: 49 解决: 15

题目描述
给出一个整数  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  k 
x1  y1 
x2  y2 
...  ... 
xn  yn 
输出
一个整数(满足条件的个数)
样例输入
234  2 
2  5 
3  6 
样例输出
4


#include<cstdio>
#include<string>
#include<set>
#include<iostream>
using namespace std;
int num[11],cnt,A[31],k;
int ans[100];
string s;
set<int>se[10];
bool vis[10]={false};
void DFS(int u)
{
    if(!vis[u])
    {
        vis[u]=true;
        cnt++;
        for(set<int>::iterator it=se[u].begin();it!=se[u].end();it++)
            DFS(*it);
    }
}
int main(void)
{
    cin>>s>>k;
    for(int i=1;i<=k;i++)
    {
        int u,v;
        cin>>u>>v;
        se[u].insert(v);
    }
    A[0]=s.length();
    for(int i=1;i<=A[0];i++) A[i]=s[i-1]-48;
    for(int i=0;i<=9;i++)
    {
        cnt=0;
        fill(vis,vis+10,0);
        DFS(i);
        num[i]=cnt;
    }
    ans[0]=1,ans[1]=1;     
    for(int i=1;i<=A[0];i++)
    {
        for(int j=1;j<=ans[0];j++) ans[j]*=num[A[i]];
        for(int j=1;j<=ans[0];j++)
            if(ans[j]>=10)
            {
                for(int k=1;k<=ans[0];k++)
                {
                    if(ans[ans[0]]>=10) ans[0]++;
                    ans[k+1]+=ans[k]/10;
                    ans[k]%=10;
                }
            } 
    }
    for(int i=ans[0];i>=1;i--) cout<<ans[i]; 
    //cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zuimeiyujianni/p/8948132.html