洛谷 P1037 产生数

洛谷 P1037 产生数

Description

  • 给出一个整数n(n<10^30)和k个变换规则(k≤15)

    规则:

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

    规则的右部不能为零。

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

    2->5

    3->6

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

    234

    534

    264

    564

    共4种不同的产生数

    问题:

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

    求出:

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

    仅要求输出个数。

Input

  • 键盘输入,格式为:

    nk

    x1y1

    x2y2

    ... ..

    xnyn

Output

  • 屏幕输出,格式为:

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

Sample Input

234 2
2 5
3 6

Sample output

4

题解:

  • 这题是一个乘法原理 + dfs
  • 首先容易发现只需求出每位的变化数相乘即可。
  • 对于变化规则建图,然后用dfs,就可以找出每位的变化数了
  • 另:此题最后一个点要用高精度,我偷懒就用了 int128, int128的注意事项在代码结尾处
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#define int __int128
#define maxn 25
using namespace std;

struct E {int next, to;} e[maxn];
string n;
int k, cnt, ans = 1, num;
int h[maxn];
bool vis[maxn];

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

void print(int x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) print(x / 10);
    putchar(x % 10 + 48);
}

void add(int u, int v)
{
    e[++num].next = h[u];
    e[num].to = v;
    h[u] = num;
}

void dfs(int x)
{
    vis[x] = 1, cnt++;
    for(int i = h[x]; i != 0; i = e[i].next)
        if(!vis[e[i].to]) dfs(e[i].to);
}

signed main()
{
    cin >> n, k = read();
    for(int i = 1; i <= k; i++)
    {
        int u = read(), v = read();
        if(v) add(u, v);
    }
    int len = (int)n.size();
    for(int i = 0; i < len; i++)
    {
        cnt = 0, memset(vis, 0, sizeof(vis)), vis[0] = 1;
        int t = n[i] - '0';
        dfs(t);
        ans *= cnt;
    }
    print(ans);
    return 0;
}
/*
    用__int128有以下几点要注意
    1. 比赛不能用
    2. int main改为signed main
    3. 输入输出要自己写 
*/

转载于:https://www.cnblogs.com/BigYellowDog/p/11155353.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值