zoukankan      html  css  js  c++  java
  • P1032 字串变换 (字符串,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
    这个题目我一开始根本不知道怎么做...想起来cf有个c题跟这个题面好像(其实很不一样)这个题其实也是搜索,只不过路径变成了字符串的形式转换。做法其实就是把母串(a)从第一个字符开始bfs,思路很简单,但是需要注意的不少,首先是字符串的处理,在学了一堆string的操作函数之后,变换字符串容易多了;然后就是优化时间,因为如果母串里有重复的一段子串,那么它们分别进入队列bfs后,就会出现走出重复路径的现象,所以在同一位置的某一子串只需要变化一次就够了,然后又有map这个容器,可以把string和访问次数对应起来,访问过的子串就不再访问了。据说这个题目可以用双向bfs 可是感觉这样连b串都需要转换一下...太复杂了...就放弃了(其实是嫌麻烦)
    #include<bits/stdc++.h>
    
    using namespace std;
    
    int n,ans;
    string a,b;
    string x[25],y[25];
    map<string,int>vis;
    
    struct node
    {
        string t;
        int step;
    };
    
    string convert(const string &s,int pos,int k)               //按运算规则转换母串
    {
        string temp="";
        if(s.length()<pos+x[k].length())    return temp;
        for(int i=0; i<x[k].length(); i++)
        {
            if(s[pos+i]!=x[k][i])
                return temp;
        }
        temp=s.substr(0,pos);                                  //string类可以直接运算真的太方便了
        temp+=y[k];
        temp+=s.substr(pos+x[k].length());                     //sbustr(pos)取从pos开始的子串
        return temp;
    }
    
    void bfs()
    {
        queue<node> q;
        node s;
        s.t=a;
        s.step=0;
        q.push(s);
        while(!q.empty())
        {
            node now=q.front();
            q.pop();
            string temp;
            if(vis.count(now.t)==1) continue;
            if(now.t==b)
            {
                ans=now.step;
                break;
            }
            vis[now.t]=1;
            for(int i=0; i<now.t.length(); i++)       //逐个字符搜索
                for(int j=0; j<n; j++)                //逐个转换方式搜索
                {
                    temp=convert(now.t,i,j);
                    if(temp!="")
                    {
                        node next;
                        next.t=temp;
                        next.step=now.step+1;
                        q.push(next);
                    }
                }
        }
        if(ans>0 && ans<=10)
            cout<<ans<<endl;
        else
            cout<<"NO ANSWER!"<<endl;
    }
    
    int main()
    {
        cin>>a>>b;
        while(cin>>x[n]>>y[n])         //不知道多少组数据 只剩ctrl+z结束输入
            n++;
        bfs();
        return 0;
    }
    View Code
  • 相关阅读:
    单链表的基本操作(查找,插入,删除)
    线性表的基本操作(插入,删除,查找)
    双人五子棋对战(需要EasyX图像库)
    2016ACM竞赛训练暑期课期末考试 a题
    百练_1664 放苹果
    百练_4120 硬币(DP)
    PAT_1046 划拳
    PAT_1026 程序运行时间
    学Android开发 这19个开发工具助你顺风顺水
    JAVA利用axis2发布webservice
  • 原文地址:https://www.cnblogs.com/youchandaisuki/p/8700921.html
Copyright © 2011-2022 走看看