1. 程式人生 > >洛谷 P1037 產生數

洛谷 P1037 產生數

orange i++ strong 過大 ac代碼 style open 另一個 -html

題目描述

給出一個整數n(n<10^30)k個變換規則(k15)。

規則:

一位數可變換成另一個一位數:

規則的右部不能為零。

例如:n=234。有規則(k=2):

2->5
3->6
上面的整數234經過變換後可能產生出的整數為(包括原數):

234
534
264
564
4 種不同的產生數

問題:

給出一個整數 n 和k 個規則。

求出:

經過任意次的變換(0次或多次),能產生出多少個不同整數。

僅要求輸出個數。

輸入輸出格式

輸入格式:

鍵盤輸入,格式為:

n k
x1? y1
x2? y2
... ...

xn ?yn?

輸出格式:

屏幕輸出,格式為:

1個整數(滿足條件的個數):

輸入輸出樣例

輸入樣例#1:
234 2
2 5
3 6
輸出樣例#1:
4
解題思路:
高精度+Floyd,先用Floyd求每一個數有幾種變換可能,再將每一位的可能數相乘,因為數據過大,需要用高精度.
AC代碼:

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 string n;
 6 int k,f[10],num[101];
 7 bool vis[10][10];//vis[i][j] = 1表示i可以變換到j 
8 9 void floyd() {//求出所有數是否能變換為其他數 10 for(int p = 0;p <= 9; p++) 11 for(int i = 0;i <= 9; i++) 12 for(int j = 0;j <= 9; j++) 13 vis[i][j] = vis[i][j] || (vis[i][p] && vis[p][j]); 14 } 15 16 int main() 17 { 18 ios::sync_with_stdio(false
); 19 cin >> n >> k; 20 while(k--) { 21 int a,b; 22 cin >> a >> b; 23 vis[a][b] = true; 24 } 25 for(int i = 0;i <= 9; i++) vis[i][i] = true;//每個數都可以從自己變到自己 26 floyd(); 27 for(int i = 0;i <= 9; i++) 28 for(int j = 0;j <= 9; j++) 29 if(vis[i][j]) f[i]++;//記錄每一個數有幾種變換可能 30 int len = 2; 31 num[1] = 1; 32 for(int i = 0;i < (int)n.length(); i++) {//高精度過程 33 for(int j = 1;j <= 100; j++) num[j] *= f[n[i]-0]; 34 for(int j = 1;j <= 100; j++) { 35 num[j+1] += num[j] / 10; 36 num[j] %= 10; 37 } 38 while(num[len]) len++; 39 } 40 for(int i = len - 1;i >= 1; i--) cout << num[i]; 41 return 0; 42 }

//NOIP普及 2002 T3

洛谷 P1037 產生數