产生数

lzusa 发布于 2019-04-19 3 次阅读


题目描述

给出一个整数 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

思路

这题可以以用乘法原理到ans=f[0]f[1]...f[9]
然后用floyd求出每一个数可以到达的其它的数,
然后要注意每一个数可能有多个,所以就要将某些数反复加
然后因为数会很大,所以要用实型或高精度进行计算

#include 
#include 
using namespace std;
bool a[11][11];
long long f[11],b[11],c[11],d[11];
int main()
{
    char st[50];
    int n;
    for (int i=0;i<=9;i++)
        f[i]=1;
    scanf("%s %d",&st,&n);
    for (int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        a[x][y]=1;
    }
    for (int k=0;k<=9;k++)
        for (int i=0;i<=9;i++)
            for (int j=0;j<=9;j++)
                a[i][j]=a[i][j] or (a[i][k] and a[k][j]);

    for (int i=0;i<=9;i++)
    {
        for (int j=0;j<=9;j++)
            if (a[i][j]==1&&i!=j)
            {
                f[i]++;
            }
    }
    for (int i=0;i<=9;i++)
        c[i]=f[i];

    for (int i=0;i<=strlen(st)-1;i++)
    {
        d[int(st[i])-int('0')]=1;
        if (b[int(st[i])-int('0')]>=1)
        {
            f[int(st[i])-int('0')]=f[int(st[i])-int('0')]*c[int(st[i])-int('0')];
        }
        b[int(st[i])-int('0')]++;
    }
    double ans=1;
    for (int i=0;i<=9;i++)
        if (d[i]==1)
            ans=ans*f[i];
    printf("%0.0lf",ans);
}
]]>