P1037 [NOIP2002 普及组] 产生数
[NOIP2002 普及组] 产生数
题目描述
给出一个整数 n n n 和 k k k 个变换规则。
规则:
- 一位数可变换成另一个一位数。
- 规则的右部不能为零。
例如: n = 234 , k = 2 n=234,k=2 n=234,k=2。有以下两个规则:
- 2 ⟶ 5 2\longrightarrow 5 2⟶5。
- 3 ⟶ 6 3\longrightarrow 6 3⟶6。
上面的整数 234 234 234 经过变换后可能产生出的整数为(包括原数):
- 234 234 234。
- 534 534 534。
- 264 264 264。
- 564 564 564。
共 4 4 4 种不同的产生数。
现在给出一个整数 n n n 和 k k k 个规则。求出经过任意次的变换( 0 0 0 次或多次),能产生出多少个不同整数。
仅要求输出个数。
输入格式
第一行两个整数 n , k n,k n,k,含义如题面所示。
接下来 k k k 行,每行两个整数 x i , y i x_i,y_i xi,yi,表示每条规则。
输出格式
共一行,输出能生成的数字个数。
样例 #1
样例输入 #1
234 2
2 5
3 6
样例输出 #1
4
提示
对于 100 % 100\% 100% 数据,满足 n < 1 0 30 n \lt 10^{30} n<1030, k ≤ 15 k \le 15 k≤15。
【题目来源】
NOIP 2002 普及组第三题
#include<bits/stdc++.h>
using namespace std;
int tag[10][10];
int d[10];
int p[1000];
int main(){
string a;
int n;
while(cin>>a>>n){
int x,y;
for(int i=0;i<n;i++){
cin>>x>>y;
tag[x][y]=1;
}
for(int k=1;k<=9;k++)
for(int i=0;i<=9;i++)
for(int j=0;j<=9;j++)
if(tag[i][k]&&tag[k][j]) tag[i][j]=1;
for(int i=0;i<10;i++){
tag[i][i]=1;
for(int j=0;j<10;j++)
if(tag[i][j])
d[i]++;
}
int z=0;
p[0]=1;
for(int i=0;a[i];i++){
z=0;
int x=d[a[i]-'0'];
for(int i=0;i<500;i++){
p[i]=(p[i]*x+z);
z=p[i]/10;
p[i]%=10;
}
}
int i=500;
while(p[i]==0) i--;
for(;i>=0;i--){
cout<<p[i];
}
cout<<endl;
}
}