(高精度+思维)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次或多次),能产生出多少个不同整数。

仅要求输出个数。

输入输出格式

输入格式:

键盘输入,格式为:

n k
x_1 y_1
x_2 y_2
... ...

x_n y_n​

输出格式:

屏幕输出,格式为:

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

输入输出样例

输入样例#1: 复制

234 2
2 5
3 6

输出样例#1: 复制

4

题解:这道题有点排列组合的意思,统计每一位可以变换到其他数字的个数,使其连乘

WA代码(没有用高精度)

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
#define nth(k,n) nth_element(a,a+k,a+n);  // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,离散化
#define Catalan C(2n,n)-C(2n,n-1)  (1,2,5,14,42,132,429...) // 卡特兰数
using namespace std;

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

typedef long long ll;
const double pi = atan(1.)*4.;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int M=63;
const int N=1e5+5;
set<char>ss;
string s;
vector<char>vect[10];
int n,v[20]; ll cut=0;
void dfs(char c){
     int u=c-'0';
     if(v[u]) return ;
     v[u]=1;
     cut++;
     for(int i=0;i<vect[u].size();i++)
         dfs(vect[u][i]);
}
int main(){
    cin>>s;  char c1,c2;
    int len=s.length();
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf(" %c %c",&c1,&c2);
        ss.insert(c1);
        vect[c1-'0'].push_back(c2);
    }
    ll ans=1;
    for(int i=0;i<len;i++){
        ll sum=1;
        if(ss.count(s[i])){
            cut=0;
            memset(v,0,sizeof(v));
            dfs(s[i]);
            sum=cut;
        }
        ans*=sum;
    }
    printf("%lld\n",ans);
    return 0;
}

AC(有高精度)

import java.math.*;
import java.util.*;

public class Main{
    static int[][] a=new int[31][16];
    static int v[]=new int[10]; 
    static int vv[]=new int[10];
    static BigInteger sum=BigInteger.ZERO;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		for(int i=0;i<30;i++)
			for(int j=0;j<15;j++)
				a[i][j]=-1;
		Scanner in=new Scanner(System.in);
		BigInteger k=in.nextBigInteger();
		String s=k.toString();
		int len=s.length();
		int n=in.nextInt();
		int c1,c2;
		for(int i=0;i<n;i++){
			c1=in.nextInt(); c2=in.nextInt();
			vv[c1]=1;
			for(int j=0;j<15;j++){
				if(a[c1][j]!=-1) continue;
				a[c1][j]=c2;
				break;
			}
		}
		BigInteger ans=BigInteger.ONE;
		for(int i=0;i<len;i++){
			BigInteger cut=BigInteger.ONE;
			if(vv[s.charAt(i)-'0']==1){
				sum=BigInteger.ZERO;
				for(int j=0;j<10;j++) v[j]=0;
			    dfs(s.charAt(i)-'0');
			    cut=sum;
			   // System.out.println("cut === "+cut);
			}
			ans=ans.multiply(cut);
		}
		System.out.println(ans);
	}
	
	static void dfs(int u){
		if(v[u]==1) return ;
		v[u]=1;
		sum=sum.add(BigInteger.ONE);
		for(int i=0;i<15;i++){
			if(a[u][i]!=-1){
                dfs(a[u][i]);
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/black_horse2018/article/details/88992919
今日推荐