码迷,mamicode.com
首页 > 其他好文 > 详细

脱水缩合

时间:2016-11-09 19:44:35      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:nod   namespace   scanf   span   src   prime   字符串   efi   struct   

技术分享

技术分享

技术分享

技术分享

源代码:

#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)的教训!
*/

脱水缩合

标签:nod   namespace   scanf   span   src   prime   字符串   efi   struct   

原文地址:http://www.cnblogs.com/Ackermann/p/6047984.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!