NOIP 2002 产生数

洛谷 P1037 产生数

https://www.luogu.org/problemnew/show/P1037

JDOJ 1298: [NOIP2002]产生数 T3

https://neooj.com:8082/oldoj/problem.php?id=1298

题目描述

给出一个整数n(n<10^{30})n(n<1030)和kk个变换规则(k \le 15)(k15)。

规则:

一位数可变换成另一个一位数:

规则的右部不能为零。

例如:n=234n=234。有规则(k=2k=2):

22->55
33->66
上面的整数234234经过变换后可能产生出的整数为(包括原数):

234234
534534
264264
564564
44 种不同的产生数

问题:

给出一个整数 nn 和kk 个规则。

求出:

经过任意次的变换(00次或多次),能产生出多少个不同整数。

仅要求输出个数。

输入输出格式

输入格式:

 

键盘输入,格式为:

n knk
x_1 y_1x1y1
x_2 y_2x2y2
... ...

x_n y_nxnyn

 

输出格式:

 

屏幕输出,格式为:

11个整数(满足条件的个数):

 

输入输出样例

输入样例#1: 复制
234 2
2 5
3 6
输出样例#1: 复制
4

#include<cstdio>
#include<cstring>
int z,ans=1,k;
int a[44],b[44];
int t[5000];
bool v[11];
char s[5000];
void dfs(int e)
{
    for(int i=1;i<=k;i++)
    {
        if(!v[b[i]]&&a[i]==e)
        {
            z++;
            v[b[i]]=true;
            dfs(b[i]);
        }
    }
}
int main()
{
    scanf("%s",s); 
    scanf("%d",&k);
    for(int i=1;i<=k;i++)
        scanf("%d%d",&a[i],&b[i]);
    int l=strlen(s);
    for(int i=0;i<l;i++)
    {
        z=0;
        int c=s[i]=s[i]-'0';
        memset(v,false,sizeof(v));
        v[c]=true;
        dfs(c);
        t[i]=1+z; 
    }
    int k[500][500];
    memset(k,0,sizeof(k));
    for(int i=l;i>=1;i--)
        t[i]=t[i-1];
    k[1][0]=1;
    k[2][0]=1;
    k[1][1]=t[1];
    for(int i=2;i<=l;i++)
    {
        k[i][0]=k[i-1][0];
        int x=0;
        for(int j=1;j<=k[i][0];j++)
        {
            k[i][j]=k[i-1][j]*t[i]+x;
            x=k[i][j]/10;
            if(k[i][j]>=10)
                k[i][j]%=10;
        }
        if(x)
        {
            k[i][0]++;
            k[i][k[i][0]]=x;
        }
    }
    for(int i=k[l][0];i>=1;i--)
        printf("%d",k[l][i]);
}

 

posted @ 2019-07-23 17:14  Seaway-Fu  阅读(449)  评论(0编辑  收藏  举报