給出乙個整數n(n<=2000)和k個變換規則(k≤15)。規則:
① 1個數字可以變換成另1個數字;
② 規則中,右邊的數字不能為零。
例如:n=234,k=2規則為
2 → 5
3 → 6
上面的整數234經過變換後可能產生出的整數為(包括原數)234,534,264,564共4種不同的產生數。
求經過任意次的變換(0次或多次),能產生出多少個不同的整數。僅要求輸出不同整數個數。
輸入格式
輸出n
kx1 y1
x2 y2
… …xn yn
格式為乙個整數(滿足條件的整數個數)。
234
22 5
3 6
4
floyd+高精度乘法。
由於每個數字可以轉化的狀態包括直接轉化和間接轉化。如對於例子:
那麼對於數字2而言,可以轉化的包括2本身,2->5,2->7,間接轉化可以依靠floyd演算法;然後將n中每個數字的轉化次數相乘就可以了。由於相乘數字很大,採用高精度乘法。236
22 5
5 7
原bfs搜尋方法,tle#include
#include
#include
#include
using
namespace std;
int cnt[10]
;//統計0到9每個數字總的轉化次數
int vis[10]
[10];
//記錄i->j是否可以轉化
struct bignum};
bignum mul
(bignum a,bignum b)
}for
(int i=
0;iwhile
(ans.num[ans.len-1]
==0) ans.len--
;//消除前導0
return ans;
}int
main
(int argc,
char
** ar**)
for(
int i=
0;i<
10;i++
) vis[i]
[i]=1;
//自身到自身可以轉化
for(
int k=
1;k<
10;k++)}
}for
(int i=
0;i<
10;i++
)// printf("%d\n",cnt[i]);
}
bignum ans;ans.num[0]
=1;ans.len=1;
for(
int i=
0;n[i]
;i++
) ans=
mul(ans,tmp);}
for(
int i=ans.len-
1;i>=
0;i--
)printf
("%d"
,ans.num[i]);
printf
("\n");
return0;
}
解決方法就是利用廣搜,注意每次替換為新的數時的處理。
# include
# include
# include
using
namespace std;
queue<
int> q;
int vis[
10000];
struct e po[16]
;int
main()
int wei=1;
while
(x>0)
}}x/=10
; wei*=10
;}q.
pop();
}printf
("%d\n"
,cnt);}
return0;
}
洛谷 P1037 產生數
description 給出乙個整數 n n 10 30 和 k 個變換規則 k 15 規則 一位數可變換成另乙個一位數 規則的右部不能為零。例如 n 234。有規則 k 2 2 5 3 6 上面的整數 234 經過變換後可能產生出的整數為 包括原數 234 534 264 564 共 4 種不同的...
洛谷P1037 產生數
題目鏈結 本著 水題不可大做 的原則,我直接字串hash 爆搜,成功爆棧。我們發現,依次搜尋每一位能取到的數字個數,最後乘起來即可 乘法原理 然後又爆了乙個點。long long存不下!於是我面向資料程式設計,看到輸出的數後面有很多0 就產生了這個神奇的騙分做法 include include in...
洛谷 P1037 產生數
給出乙個整數n n 2000 和k個變換規則 k 15 規則 1個數字可以變換成另1個數字 規則中,右邊的數字不能為零。例如 n 234,k 2規則為 2 5 3 6 上面的整數234經過變換後可能產生出的整數為 包括原數 234,534,264,564共4種不同的產生數。求經過任意 次的變換 0次...