• [luogu p1032] 字串变化


    传送门

    题面

    题目描述

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

    (A_1)​ -> (B_1)

    (A_2)​ -> (B_2)

    规则的含义为:在 (A)中的子串 (A_1)​ 可以变换为 (B_1)​,(A_2)​ 可以变换为 (B_2)​ …。

    例如:(A)=abcd(B)xyz

    变换规则为:

    abc→xu,ud→y,y→yz

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

    abcd→xud→xy→xyz

    共进行了(3)次变换,使得(A)变换为(B)

    输入输出格式

    输入格式

    输入格式如下:

    (A) (B)
    (A_1)(B_1)
    (A_2​) (B_2)​ |-> 变换规则

    ... ... /

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

    输出格式

    输出至屏幕。格式如下:

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

    输入输出样例

    样例

    输入 #1

    abcd xyz
    abc xu
    ud y
    y yz
    

    输出 #1

    3
    

    分析

    给定一些变换规则,求最少步数?明显是广搜吧,因为广搜首解最优,只要搜索搜到(B),输出答案就行。
    这道题还可以灵活的运用STL,让码量大幅下降。首先要铺垫几个前置知识:
    首先是find,这个函数怎么用呢。来看下面的代码片段:

    string str = "To be, or not to be - that is the question.";
    str.find("be"); // 3 (To be)的be
    str.find("be",4); // 17 (to be)的be 
    

    也就是说,a.find(b)的含义是在a字符串中找到第一个字符串b的位置,返回字符串b的第一个字符在字符串a的位置。
    a.find(b,pos)的含义是在a字符串中找到在第pos个位置后第一个字符串b的位置,返回字符串b的第一个字符在字符串a的位置。
    如果找不到,会返回string :: npos,也就是说a.find(b)如果a字符串中并不包含字符串b,会返回string :: npos,在一些编译器中,它的值为-1,也有可能是4294967295。所以建议直接写string :: npos
    同样的,还有rfind,倒序寻找,这里不再多说。

    然后再介绍一个replace,他是什么意思呢,

    string str = "He have a dream.";
    str.replace(3,4,"has")// He has a dream.
    

    也就是说,a.replace(pos,n,b)的意思是在a字符串中的第pos个位置和后面n个字符替换成字符串b。无返回值哦!

    介绍完了也没啥可说的了,上代码咯!

    代码

    /*
     * @Author: crab-in-the-northeast 
     * @Date: 2020-02-19 11:32:51 
     * @Last Modified by: crab-in-the-northeast
     * @Last Modified time: 2020-02-19 11:35:07
     */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <cstdlib>
    using namespace std;
    
    const int maxn = 15;
    
    struct node{
        string str;
        int step;
    };
    
    string a,b;
    string rulea[maxn];
    string ruleb[maxn];
    int rules = 1;
    
    void bfs(){
        queue<node> q;
        node now;
        now.str = a;
        now.step = 0;
        q.push(now);
    
        while(!q.empty()){
            now = q.front();
            q.pop();
            for(int i = 1; i <= rules; i++){
                int pos = now.str.find(rulea[i],0);
                while(1){
                    if(pos == string::npos) break;
                    node nxt;
                    nxt.str = now.str;
                    nxt.str.replace(pos,rulea[i].size(),ruleb[i]);
                    nxt.step = now.step+1;
                    if(nxt.str == b){
                        printf("%d
    ",nxt.step);
                        exit(0);
                    }
                    if(nxt.step > 10){
                        printf("NO ANSWER!
    ");
                        exit(0);
                    }
                    pos = now.str.find(rulea[i],pos+1);
                    q.push(nxt);
                }
            }
        }
        printf("NO ANSWER!
    ");
        return ;
    }
    
    int main(){
        cin>>a>>b;
        while(cin>>rulea[rules]&&cin>>ruleb[rules]) rules++;
        rules--;
        bfs();
        return 0;
    }
    

    结果

    竟然忘记q.push(nxt),我服了我自己。WA0
    AC100

    over.

  • 相关阅读:
    Android检验下载的文件的完整性
    RecyclerView与SwipeRefreshLayout等组合使用后宽度不能填满
    android断点续传实现方案之三
    博客美化,页首波浪
    博客美化,页首的飘雪效果
    博客美化,博客背景图片设置
    博客美化,页脚游动的鱼
    博客美化,左侧下面的卡通小姐姐
    博客美化,右下角的卡通小姐姐
    .Net工厂方法模式(Factory Method Pattern)
  • 原文地址:https://www.cnblogs.com/crab-in-the-northeast/p/luogu-p1032.html
Copyright © 2020-2023  润新知