NOIP 2002 产生数
洛谷 P1037 产生数
https://www.luogu.org/problemnew/show/P1037
JDOJ 1298: [NOIP2002]产生数 T3
https://neooj.com:8082/oldoj/problem.php?id=1298
题目描述
给出一个整数n(n<10^{30})n(n<1030)和kk个变换规则(k \le 15)(k≤15)。
规则:
一位数可变换成另一个一位数:
规则的右部不能为零。
例如:n=234n=234。有规则(k=2k=2):
22->55
33->66
上面的整数234234经过变换后可能产生出的整数为(包括原数):
234234
534534
264264
564564
共44 种不同的产生数
问题:
给出一个整数 nn 和kk 个规则。
求出:
经过任意次的变换(00次或多次),能产生出多少个不同整数。
仅要求输出个数。
输入输出格式
输入格式:
键盘输入,格式为:
n knk
x_1 y_1x1y1
x_2 y_2x2y2
... ...
x_n y_nxnyn
输出格式:
屏幕输出,格式为:
11个整数(满足条件的个数):
输入输出样例
输入样例#1: 复制
234 2 2 5 3 6
输出样例#1: 复制
4
#include<cstdio> #include<cstring> int z,ans=1,k; int a[44],b[44]; int t[5000]; bool v[11]; char s[5000]; void dfs(int e) { for(int i=1;i<=k;i++) { if(!v[b[i]]&&a[i]==e) { z++; v[b[i]]=true; dfs(b[i]); } } } int main() { scanf("%s",s); scanf("%d",&k); for(int i=1;i<=k;i++) scanf("%d%d",&a[i],&b[i]); int l=strlen(s); for(int i=0;i<l;i++) { z=0; int c=s[i]=s[i]-'0'; memset(v,false,sizeof(v)); v[c]=true; dfs(c); t[i]=1+z; } int k[500][500]; memset(k,0,sizeof(k)); for(int i=l;i>=1;i--) t[i]=t[i-1]; k[1][0]=1; k[2][0]=1; k[1][1]=t[1]; for(int i=2;i<=l;i++) { k[i][0]=k[i-1][0]; int x=0; for(int j=1;j<=k[i][0];j++) { k[i][j]=k[i-1][j]*t[i]+x; x=k[i][j]/10; if(k[i][j]>=10) k[i][j]%=10; } if(x) { k[i][0]++; k[i][k[i][0]]=x; } } for(int i=k[l][0];i>=1;i--) printf("%d",k[l][i]); }