我是靠谱客的博主 酷酷曲奇,这篇文章主要介绍(数学)P1037 产生数,现在分享给大家,希望可以做个参考。

一、算法分析

开始时写了一个搜索,果断超时,然后意识到答案就是每一位的转移可能种类的乘积。然后果断祭出离散数学,一发传递闭包加高精AC。

二、代码及注释

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; string st; int n; int len; int mp[10][10]; int d[10]; int ans[10000]; int b[10000]; int c[10000]; void calc(int x){ memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); int cnt=0; while(x){ b[++cnt]=x%10; x/=10; } b[0]=cnt; for(int i=1;i<=ans[0];i++) for(int j=1;j<=b[0];j++){ c[i+j-1]+=ans[i]*b[j]; } int len=ans[0]+b[0]; for(int i=1;i<len;i++) if(c[i]>=10){ c[i+1]+=c[i]/10; c[i]%=10; } while(c[len]==0 && len>1) len--; ans[0]=len; for(int i=1;i<=len;i++) ans[i]=c[i]; } int main(){ cin>>st>>n; int u,v; for(int i=1;i<=n;i++){ cin>>u>>v; mp[u][v]=1; } for(int k=1;k<=9;k++) for(int i=0;i<=9;i++) for(int j=1;j<=9;j++){ //这里求一下传递闭包 if(mp[i][k] && mp[k][j]) mp[i][j]=1; } for(int i=0;i<=9;i++){ mp[i][i]=1; //自环 for(int j=0;j<=9;j++){ if(mp[i][j]) d[i]++; } } ans[0]=1; ans[1]=1; int lent=st.length(); for(int i=0;i<lent;i++){ //将每一位的情况乘起来 int p=d[st[i]-'0']; //当前的转移数目 calc(p); } for(int i=ans[0];i>=1;i--) cout<<ans[i]; return 0; }

最后

以上就是酷酷曲奇最近收集整理的关于(数学)P1037 产生数的全部内容,更多相关(数学)P1037内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(94)

评论列表共有 0 条评论

立即
投稿
返回
顶部