題目傳送門
最開始錯誤的思路是對整條字串進行dfs,看一位dfs進入下一位,這是沒有充分理解題意的後果
核心解題思路:不要被這些規則變來變去搞混了,我們需要將原問題進行切割成小的子問題去分析。例如此處我們將每一位數都當做乙個獨立單位,首先求出在這個位置上有多少種可以存在的數的種類(0~9)。而這些獨立單位(位置)互不相同,彼此獨立,因此求出總的可變換的數的總數則是每個位置上的數的種類的累乘。對每一位上的數操作時,把變換的規則當做是點與點的連線(一共有10個點位0~9)。因此想要訪問所有能走的點(有多少點則有個種類的數),因此這一遍歷全部圖的思想符合dfs的性質
注意:在數的第乙個位置上,我們假設0的存在是合法的,比如0123實際上是123,但它也帶來了乙個新的數字,因此種類也會增加
實現**:
1 #include2using
namespace
std;
3#define lll __uint128_t45
char s[100]; //
用於儲存整數
6int memory[100]=; //
用於數有多少種變換種類 實質是乙個優化,記憶化儲存
7 lll ans; //
用於儲存數的種類
8int num=0; //
記錄每個位置上有多少種類數
9int flag[100]=; //
用於dfs中標誌 同樣直接拿字元'0'~'9'當做下標
10int k=0; //
規則數
11char a[20],b[20]; //
儲存變換規則
1213
void
out(lll x)
17void dfs(char
index)
27}
28return;29
30}
31int
main()
4142
for(int i=0;s[i]!='
\0';i++)else
51 ans*=num;
52}
53out(ans); //
輸出種類數
54return0;
55 }
補充說明:__uint128_t是乙個較大的型別,而且符合gcc標準,在很多oj平台上可以使用。但其輸出函式不能用cout或者printf,需要自己重寫。詳細解釋見:這裡。
如果不用此型別,則需要高精度乘法演算法來實現程式。
洛谷 P1037 產生數
description 給出乙個整數 n n 10 30 和 k 個變換規則 k 15 規則 一位數可變換成另乙個一位數 規則的右部不能為零。例如 n 234。有規則 k 2 2 5 3 6 上面的整數 234 經過變換後可能產生出的整數為 包括原數 234 534 264 564 共 4 種不同的...
洛谷P1037產生數
給出乙個整數n n 2000 和k個變換規則 k 15 規則 1個數字可以變換成另1個數字 規則中,右邊的數字不能為零。例如 n 234,k 2規則為 2 5 3 6 上面的整數234經過變換後可能產生出的整數為 包括原數 234,534,264,564共4種不同的產生數。求經過任意次的變換 0次或...
洛谷P1037 產生數
題目鏈結 本著 水題不可大做 的原則,我直接字串hash 爆搜,成功爆棧。我們發現,依次搜尋每一位能取到的數字個數,最後乘起來即可 乘法原理 然後又爆了乙個點。long long存不下!於是我面向資料程式設計,看到輸出的數後面有很多0 就產生了這個神奇的騙分做法 include include in...