【AC代碼】
#include <iostream>#include <cstdio> //cstdio內(nèi)有scanf()函數(shù)#include <cstring> //cstring內(nèi)有strlen(),memset()函數(shù)using namespace std;char num[32]; //字符型num數(shù)組用于輸入做變換的巨大數(shù)字,它最多長達31位數(shù)int value[32]={0,1}; //value[1]設為1,既是乘法的開始,也是k=0這種情況的特殊結(jié)果int change[10][10]; //bool型的change[i][j]儲存是否存在從i向j的變換int node[10]; //bool型的node[n]記錄n這種變換結(jié)果是否被記錄過int factor; //factor記錄每一位上可能的變換結(jié)果的總數(shù),所有位上的factor相乘得到的即是所求的種類總數(shù)int multilen=1; //變化的multilen反映的是當前高精度乘法結(jié)果的位數(shù)void DFS(int n) //深度優(yōu)先搜索一個數(shù)字{ int j; if(node[n]) //如果node[n]為1,表示n這種變換結(jié)果已被記錄過 return ; //這時再向下搜索得到的也只是與之前重復的情況,這時候就不必再DFS,只要返回上一個DFS(調(diào)用該DFS的DFS) else //如果node[n]為0,表示n這種結(jié)果沒有被記錄過 { node[n]=1; //下面要記錄它,將node[n]設為1 factor++; //用全局變量factor因子記錄這種情況 } for(j=0;j<=9;j++) //對于這10個數(shù)字j if(change[n][j]) //如果存在從n向j的變換 DFS(j); //那么我們就變換,搜索變換后的j}void multiply() //高精度乘法,將因子factor乘入數(shù)組value[]{ int carry=0; //carry表示每次乘法需要進位的數(shù)字 for(int i=1;i<=multilen;i++) //從第一位到最后一位每一位都要乘 { value[i]=value[i]*factor+carry; //乘上因子factor,再加上上一位留下的進位數(shù)carry carry=value[i]/10; //carry再變成當前這一位對下一位產(chǎn)生的進位數(shù) value[i]%=10; //進位后,本位當然要對10取余 } if(carry>0) //如果到最后一位也乘完,還存在向下一位的進位數(shù)carry value[++multilen]=carry; //那么總位數(shù)就要增加一位,并將進位數(shù)放進去}int main(){ int k,i,j,length; //length將儲存num的長度 scanf("%s%d",num,&k); //用scanf以跳過空格 memset(change,0,sizeof(change)); //change[i][j]為0時表示不存在從i向j的變換,先清零,再在后面賦1 while(k--) { cin>>i>>j; change[i][j]=1; //change[i][j]為1時表示存在從i向j的變換 } length=strlen(num); //這樣做僅避免反復的求長度運算 for(i=0;i<length;i++) //遍歷輸入數(shù)字的每一位數(shù) { memset(node,0,sizeof(node)); //每次將DFS節(jié)點數(shù)組node[]清空 factor=0; //factor臨時儲存每一位的因子 DFS(num[i]-'0'); //對每一位深度優(yōu)先搜索能做多少次變換 multiply(); //將因子相乘(高精度)放入數(shù)組value[] } for(i=multilen;i>=1;i--) cout<<value[i]; //從高位到低位輸出每一位數(shù)return 0;}
新聞熱點
疑難解答