[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\n",nxt.step);
                    exit(0);
                }
                if(nxt.step > 10){
                    printf("NO ANSWER!\n");
                    exit(0);
                }
                pos = now.str.find(rulea[i],pos+1);
                q.push(nxt);
            }
        }
    }
    printf("NO ANSWER!\n");
    return ;
}

int main(){
    cin>>a>>b;
    while(cin>>rulea[rules]&&cin>>ruleb[rules]) rules++;
    rules--;
    bfs();
    return 0;
}

结果

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

over.

posted @ 2020-02-19 12:51  dbxxx  阅读(210)  评论(0编辑  收藏  举报