码迷,mamicode.com
首页 > 其他好文 > 详细

NOIP2002 产生数

时间:2014-11-25 12:44:58      阅读:368      评论:0      收藏:0      [点我收藏+]

标签:c++

题目描述

给出一个整数n(n<1030) 和k个变换规则(k<=15)。

规则:

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

        规则的右部不能为零。

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

                 2->5

                 3->6

        上面的整数234经过变换后可能产生出的整数为(包括原数):

                 234

                 534

                 264

                 564

        共4种不同的产生数

问题:

  给出一个整数n和k个规则。

求出:

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


输入格式

每个测试文件只包含一组测试数据,每组输入的第一行输入两个整数n和k(n<1030k<=15)。

接下来k行每行输入一个规则,每个规则由两个整数构成。


输出

对于每组输入数据,输出一个整数,表示满足条件的个数。


样例输入

234 2
2 5
3 6

样例输出

4


需要考虑两点

1一共有15种操作  说明一个数可以变成多个不同

如果存在 2个操作 a->b   b->c   则a既可以变到b也可以变到c

所以可以通过DFS求每个数可变得其他数的个数


2、最多可能有30位数 所以最大可能9^30

需要模拟大数乘法 而每次乘数有一个 不超过10 所以并不难

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int op[10][10];           
char str[105];
int vis[10];
int value[32];
int maxlen=1;
void dfs(int a)         //搜索出每个数可以到达的数的个数   用SS保存
{
    if(vis[a])
        return;
    vis[a]=1;
    ss++;
    for(int i=0;i<=9;i++)
    {
        if(op[a][i]==1)
            dfs(i);
    }
}
void multiple(int x)             //最大可能 9^30 超long long  所有模拟大数乘法
{
    int carry=0;                 //carry表示进位
    for(int i=1;i<=maxlen;i++)
    {
        value[i]=value[i]*x+carry;
            carry=value[i]/10;
            value[i]=value[i]%10;
    }
    if(carry>0)               
        value[++maxlen]=carry;
    return;
}
int main()
{
    int m,n,i,j,k;
    int s;
    value[1]=1;
    memset(op,0,sizeof(op));
    scanf("%s%d",str,&k);
    int a,b;
    if(k==0)               
    {
        cout<<1<<endl;
        return 0;
    }
    while(k--)
    {
        scanf("%d%d",&a,&b);
        op[a][b]=1;               //op[a][b]代表a可以到b
    }
    int len=strlen(str);
    for(i=0;i<len;i++)
    {
        memset(vis,0,sizeof(vis));
        ss=0;
        dfs(str[i]-'0');          //求出每位可转换数的乘积   //其实可以用一个数组保存每个数可转换的数的个数  
        multiple(ss);
    }
    for(i=maxlen;i>=1;i--)
        cout<<value[i];
    cout<<endl;
    return 0;
}




NOIP2002 产生数

标签:c++

原文地址:http://blog.csdn.net/axuan_k/article/details/41479705

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!