【codevs1099】字串变换(双端bfs)

这个题之前是用普通的bfs写出的,现在复习,觉得可以用这个练习一下双端bfs,毕竟这可是咔咔咔剪了一大堆枝呢。

这个题如果用普通bfs去求的话,唯一的难点就在于对字符串的操作,查找可以用find来做,修改则用replace。双端bfs也是差不多,只不过多加了个队列,一个存从起点跑到的点,另一个存从终点跑到的点,当发现这个点已经被跑到过了,则说明可以到达终点,如果跑完一遍所有的状态都没发现跑到之前走过的点,就说明无解。但是双端bfs要比普通的bfs不知快到哪里去了,普通的456ms,双端的则只需3ms。

ps:hash的进制数一定要开大点 ,我就说因为开太小wa了半天

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
const int mod=997219;
using namespace std;
struct in
{
    int ceng;
    string s;
}f,l;
string a[10],b[10];
int n,ha1[mod],ha2[mod],ha3[mod],ha4[mod],ans;
queue<in>qwq,qaq;
inline int hash(in x)
{
    int re=1;
    for(int i=0;i<x.s.length();i++)
        re=(re*27%mod+x.s[i]-'('+1);
    re%=mod;
    return re;
}
inline int hash1(in x)
{
    int re=1;
    for(int i=x.s.length()-1;i>=0;i--)
        re=(re*27%mod+x.s[i]-'('+1);
    re%=mod;
    return re;
}
int bfs()
{
    qwq.push(f),qaq.push(l);
    while(!qwq.empty()&&!qaq.empty())
    {
        in owo=qwq.front(),wow=qaq.front(),x,y;
        for(int i=1;i<=n;i++)
        {
            for(int j=owo.s.find(a[i],0);j<owo.s.length();j=owo.s.find(a[i],j+1))
            {
                x=owo;
                y.ceng=x.ceng+1;
                y.s=x.s.replace(j,a[i].length(),b[i]);
                if(y.ceng>5)
                    return -1;
                if(ha2[hash(y)]&&ha4[hash1(y)])
                    return ha2[hash(y)]+y.ceng;
                qwq.push(y),ha1[hash(y)]=ha3[hash1(y)]=y.ceng;
            }
            for(int j=wow.s.find(b[i],0);j<wow.s.length();j=wow.s.find(b[i],j+1))
            {
                x=wow;
                y.ceng=x.ceng+1;
                y.s=x.s.replace(j,b[i].length(),a[i]);
                if(y.ceng>5)
                    return -1;
                if(ha1[hash(y)]&&ha3[hash1(y)])
                    return ha1[hash(y)]+y.ceng;
                qaq.push(y),ha2[hash(y)]=ha4[hash1(y)]=y.ceng;
            }
        }
        qwq.pop(),qaq.pop();
    }
    return -1;
}
int main()
{
    cin>>f.s>>l.s;
    n=1;
    while(cin>>a[n]>>b[n])
        n++;
    n--;
    ans=bfs();
    if(ans==-1)
        cout<<"NO ANSWER!";
    else
        printf("%d",ans);
}

 

posted @ 2017-10-13 09:35  那一抹落日的橙  阅读(538)  评论(0)    收藏  举报