洛谷 P1037 產生數
阿新 • • 發佈:2019-03-03
orange i++ strong 過大 ac代碼 style open 另一個 -html
題目描述
給出一個整數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
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可以變換到j8 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 產生數