• 【洛谷】【计数原理+Floyed】P1037 产生数


    【题目描述:】

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

    规则:

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

    规则的右部不能为零。

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

    2 -> 5
    3 -> 6

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

    234
    534
    264
    564

    共 4 种不同的产生数

    【问题:】

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

    求出:

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

    仅要求输出个数。


    [算法分析:]

    读入一个整数a,每一位分别为(a_1), (a_2), (a_3),..., (a_n)

    设置一个数组num,num[i]表示数字i有多少种变换,

    于是答案为(num[a_1] * num[a_2] * ... * num[a_n])

    写出来一看,发现在

    1234 3
    2 3
    3 2
    3 5

    这组数据下的结果是错误的,

    2变成3后,可以继续变成5,所以2能变成的值有两个

    如何统计?

    f[i][j]=1 表示数字i能变成数字j,对f数组做一遍Floyed,再遍历一遍f数组即可统计。


    [Code:]

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int k;
    long long num1[10];
    bool a[10][10];
    char n[31], ans[205], num[10][101];
    
    int aa[205], b[205], c[205];
    char ss[205];
    //需用高精度
    void Mul(char s1[], char s2[]) {
    	memset(ss, 0, sizeof(ss));
    	memset(aa, 0, sizeof(aa));
    	memset(b, 0, sizeof(b));
    	memset(c, 0, sizeof(c));
    	int lena=strlen(s1), lenb=strlen(s2);
    	
        for(int i=0; i<lena; i++) aa[i] = s1[lena-i-1]-'0';
        for(int i=0; i<lenb; i++) b[i] = s2[lenb-i-1]-'0';
        for(int i=0; i<lena; i++)
            for(int j=0; j<lenb; j++) {
                c[i+j] += aa[i]*b[j];
                c[i+j+1] += c[i+j]/10;
                c[i+j] %= 10;
            }
        int lenc = lena+lenb;
        while(lenc>1 && c[lenc-1]==0) lenc--;
        
        for(int i=lenc-1; i>=0; i--)
        	ss[lenc-i-1] = c[i] + '0';
    }
    
    int main() {
        for(int i=0; i<=9; ++i) num1[i] = 1;
        scanf("%s%d", n, &k);
        for(int i=1; i<=k; ++i) {
            int x, y;
            scanf("%d%d", &x, &y);
            a[x][y] = 1;
        }
        for(int k=0; k<10; ++k)
        for(int i=0; i<10; ++i)
        for(int j=0; j<10; ++j)
        	a[i][j] |= (a[i][k] & a[k][j]);
        for(int i=0; i<10; ++i)
        	for(int j=0; j<10; ++j)
        		if(a[i][j] && i!=j) {
        			++num1[i];
    			}
    	for(int i=0; i<10; ++i)
    		sprintf(num[i], "%lld", num1[i]);
        int l = strlen(n);
        ans[0] = '1';
        for(int i=0; i<l; ++i) {
        	Mul(ans,num[n[i]-'0']);
        	strcpy(ans, ss);
    	}
    	cout << ans;
    }
    
  • 相关阅读:
    final
    Leetcode Single Number
    Leetcode Implement strStr()
    Leetcode Count and Say
    Leetcode Paint Fence
    Leetcode Isomorphic Strings
    Leetcode Min Stack
    Leetcode Valid Sudoku
    Leetcode Two Sum III
    Leetcode Read N Characters Given Read4
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9208761.html
Copyright © 2020-2023  润新知