NOIP2002字串变换[BFS]

题目描述

已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则):

     A1$ -> B1$

     A2$ -> B2$

规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$、A2$ 可以变换为 B2$ …。

例如:A$='abcd'B$='xyz'

变换规则为:

‘abc’->‘xu’‘ud’->‘y’‘y’->‘yz’

则此时,A$ 可以经过一系列的变换变为 B$,其变换的过程为:

‘abcd’->‘xud’->‘xy’->‘xyz’

共进行了三次变换,使得 A$ 变换为B$。

输入输出格式

输入格式:

 

键盘输人文件名。文件格式如下:

A$ B$ A1$ B1$

   A2$ B2$ |-> 变换规则

... ... /

所有字符串长度的上限为 20。

输出格式:

输出至屏幕。格式如下:

若在 10 步(包含 10步)以内能将 A$ 变换为 B$ ,则输出最少的变换步数;否则输出"NO ANSWER!"

输入输出样例

输入样例#1:
abcd xyz
abc xu
ud y
y yz
输出样例#1:
3
---------------------------------------------------------------------------------------------------------------------------------------
和单词接龙有点像,都是字符串,不过这是最少次数,BFS
很多人说要双向广搜,但我随便写写也过了
用个map判重,变换时枚举规则和从哪个位置开始
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
#include<map>
using namespace std;
string st,ed,x[10],y[10];    int cnt=0;
map<string,int> step;
queue<string> q;
inline bool eq(string &s,int be,int j){
    string &tmp=x[j]; int l=min(s.size(),be+tmp.size());
    for(int i=be;i<l;i++)
        if(s[i]!=tmp[i-be]) return false;
    return true;
}
string change(string s,int be,int j){
    string nw;
    for(int i=be;i<(int)s.size()-(int)x[j].size()+1;i++)
        if(eq(s,i,j)){
            nw=s.substr(0,i)+y[j];
            if(i+x[j].size()<s.size()) nw+=s.substr(i+x[j].size(),s.size()-(i+x[j].size()));
            return nw;
        }
    return ""; 
}
int bfs(){
    q.push(st); step[st]=0;
    while(!q.empty()){
        string now=q.front(); q.pop();//cout<<now<<" "<<step[now]<<"    now
";
        int d=step[now];
        for(int i=0;i<now.size();i++)
            for(int j=1;j<=cnt;j++){
                string nw=change(now,i,j);//cout<<nw<<"    nw 
";
                if(nw=="") continue;
                if(step.count(nw)) continue;
                if((step[nw]=d+1)>10) continue;//cout<<nw<<" "<<j<<"    nw 
";
                q.push(nw);//if(nw=="xyz") cout<<step[nw]<<" hi
";
                if(nw==ed) return d+1;
            }
    }
    return false;
}
int main(){
    cin>>st>>ed; cnt=1;
    while(cin>>x[cnt]>>y[cnt]) cnt++; cnt--;//cout<<cnt<<"cnt
";    
    int ans=bfs();
    if(ans==0) cout<<"NO ANSWER!";
    else cout<<ans;
}


 
原文地址:https://www.cnblogs.com/candy99/p/5783509.html