脱水缩合
Posted 【對策局】
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了脱水缩合相关的知识,希望对你有一定的参考价值。
源代码: #include<cstdio> #include<cstring> #include<queue> #include<string> #define INF 10000007 using namespace std; struct Node { int X,Y; }i[6][37]; string S; queue <string> Q; int n,k,Sum[6]={0}; int Prime1[6]={13,11,7,5,3,2}; int Prime2[6]={17,19,23,29,31,37}; bool Flag(0),Vis1[10000007]={0},Vis2[10000007]={0}; int main() //我求的是什么,我不知道,但我求出了所有长度为n的可能的合并情况数。 { scanf("%d%d\\n",&n,&k); for (int a=0;a<k;a++) { char t,t1,t2; t1=getchar(); t2=getchar(); getchar(); t=getchar(); Sum[t-\'a\']++; i[t-\'a\'][Sum[t-\'a\']].X=t1-\'a\'; i[t-\'a\'][Sum[t-\'a\']].Y=t2-\'a\'; getchar(); } Q.push("a"); //字符串类型STL队列。 Vis1[13]=Vis2[17]=true; while (!Q.empty()) //BFS注意条件,防止死循环。 { S=Q.front(); Q.pop(); int L=S.length(); if (L==n) //后面的肯定更长,跳出。 { Flag=true; break; } char T[6]={0}; for (int a=0;a<L;a++) { int t=S[a]-\'a\',T1=1,T2=1; for (int b=0;b<a;b++) { T[b]=S[b]; //算是string转char[]。 T1=T1*Prime1[S[b]-\'a\']%INF*(b+1)%INF; //双重哈希。 T2=T2*Prime2[S[b]-\'a\']%INF*(b+1)%INF; } for (int b=a+1;b<L;b++) { T[b+1]=S[b]; T1=T1*Prime1[T[b+1]-\'a\']%INF*(b+2)%INF; T2=T2*Prime2[T[b+1]-\'a\']%INF*(b+2)%INF; } for (int b=1;b<=Sum[t];b++) { T[a]=i[t][b].X+\'a\'; T[a+1]=i[t][b].Y+\'a\'; int t1=T1,t2=T2; T1=T1*Prime1[T[a]-\'a\']%INF*(a+1)%INF*Prime1[T[a+1]-\'a\']%INF*(a+2)%INF; T2=T2*Prime2[T[a]-\'a\']%INF*(a+1)%INF*Prime2[T[a+1]-\'a\']%INF*(a+2)%INF; if (!Vis1[T1]||!Vis2[T2]) { string s(T); //char[]转string。 Vis1[T1]=Vis2[T2]=true; Q.push(s); } T1=t1; T2=t2; } } } if (Flag) //特判。 printf("%d",Q.size()+1); else printf("0"); return 0; } /* 倒着来,从"a"开始不断分裂,BFS所有情况即可。 读题还是要细心认真,不要吝惜时间。 血(WA)的教训! */
以上是关于脱水缩合的主要内容,如果未能解决你的问题,请参考以下文章