• 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;
    }
    
    
    
     
  • 相关阅读:
    虚拟机
    10亿数中找出前1000大的数
    deepin云打印实现连接Windows打印机
    如何判断一个数是否在40亿个整数中?
    大三下学期第三周总结
    使用Jenkins构建、部署spring boot项目
    大三下学期第二周总结
    谷歌zxing 二维码生成工具
    Jbarcode 条形码生成工具
    kaptcha验证码实现,配合spring boot使用
  • 原文地址:https://www.cnblogs.com/candy99/p/5783509.html
Copyright © 2020-2023  润新知