题目描述

已知有两个字串 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!"

输入输出样例

输入样例
abcd xyz
abc xu
ud y
y yz
输出样例
3
 
差不多是一道水题吧。。就是 bfs 暴搜就行。只不过在搜的时候要注意以下几点:
1.每一次是如何变换的
 string change(const string& now, int st, int num)    //now字符串第st位,第num条变换规则
{
for(int i = ; i < a1[num].length(); ++i)
{
if(st + i >= now.length()) return ""; //若超出原字符串长度或
if(now[st + i] != a1[num][i]) return ""; //有一位不符合规则,就不能变换,返回空字符串
}
string ret;
//变换分三步
for(int i = ; i < st; ++i) ret += now[i];//1.将原字符串不用变换的前半部分复制下来
ret += b1[num]; //2.再加上变换部分
for(int i = st + a1[num].length(); i < now.length(); ++i) ret += now[i];//3.加上原字符串剩下部分
return ret;
}

用 string 的好处是,它支持加减运算,就是增加或减去某一字符串,而不用库里的 strcpy 函数。

2.再用bfs时,要记录之前的状态,防止又退回去,进入死循环。但这道题开 vis 数组就不太合适,因为每一个状态是一个字符串。所以最好开一个 map 来记录状态,并判重。

3.若按 2 的方法,因为是字符串的操作,大数据可能会超时,所以可以将字符串编码为 unsigned long long,一个简单的hash

 ull hash(const string& now){
ull ret = ;
for (int i = ; i < now.length(); i++){
ret += now[i] - 'a' + ; ret *= ;
}
return ret;
}

完整代码

 #include <cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef unsigned long long ull;
const int maxn = ;
string a, b;
string a1[], b1[];
int cnt = ;
ull hash(const string& now){
ull ret = ;
for (int i = ; i < now.length(); i++){
ret += now[i] - 'a' + ; ret *= ;
}
return ret;
}
string change(const string& now, int st, int num)
{
for(int i = ; i < a1[num].length(); ++i)
{
if(st + i >= now.length()) return "";
if(now[st + i] != a1[num][i]) return "";
}
string ret;
for(int i = ; i < st; ++i) ret += now[i];
ret += b1[num];
for(int i = st + a1[num].length(); i < now.length(); ++i) ret += now[i];
return ret;
}
map<ull, int>mp; //相当于vis
void bfs()
{
mp.clear();
queue<string>q;
q.push(a); mp[hash(a)] = ;
while(!q.empty())
{
string now = q.front(); q.pop();
ull hn = hash(now);
if(mp[hn] >= ) break;
for(int i = ; i < cnt; ++i)
{
for(int j = ; j < now.length(); ++j)
{
string neww = change(now, j, i);
ull hw = hash(neww);
if(neww != "" && mp.find(hw) == mp.end())
{
q.push(neww); mp[hw] = mp[hn] + ;
if(neww == b) {printf("%d\n", mp[hw]); return;}
}
}
}
}
printf("NO ANSWER!\n");
}
int main()
{
cin >> a >> b;
while(cin >> a1[cnt] >> b1[cnt]) cnt++;
bfs();
return ;
}

值得一提的是,这里的 map 发挥了两个作用,一个是 vis 数组,另一个是相当于记录步数的 dis数组

洛谷 P1032 字串变换的更多相关文章

  1. [洛谷P1032] 字串变换

    洛谷题目链接:字串变换 题目描述 已知有两个字串 A, B 及一组字串变换的规则(至多6个规则): A1 -> B1 A2 -> B2 规则的含义为:在 A$中的子串 A1 可以变换为 B ...

  2. 洛谷 P1032 字串变换题解

    题目链接:https://www.luogu.org/problem/P1032 题目描述 已知有两个字串A,BA,B及一组字串变换的规则(至多66个规则): A_1A1​ ->B_1B1​ A ...

  3. 洛谷 P1032 字串变换 (BFS)

    题目传送门 我即使是死了,钉在棺材里了,也要在墓里,用这腐朽的声带喊出 STL大法好 这题最麻烦的其实是处理字符串,真正的搜索部分我个人认为也就只有橙题或黄题的难度.而处理字符串,正如前面所说,STL ...

  4. 洛谷 P1032 字串变换 题解

    每日一题 day19 打卡 Analysis 广搜+map判重 用find寻找字串,再用replace替换字串 这里的map相当于正常广搜的一个book的作用 #include<iostream ...

  5. 洛谷P1032 字串变换【bfs】

    题目链接:https://www.luogu.org/problemnew/show/P1032 题意: 给定一个原字符串和目标字符串,以及几个字符串变换的规则. 问能否根据这几个规则在十步之内把原字 ...

  6. 洛谷P1032 字串变换-题解

    https://www.luogu.org/problemnew/show/P1032--(题目传送) 好在数据范围很小,暴力一点也能过.思路较简单,按照所有规则,从第一位开始广搜. 注意:1.str ...

  7. 洛谷 P1032 字串变换(map)

    题目传送门 解题思路: 搜索题,因为要求最少次数,用bfs. AC代码: #include<cstdio> #include<iostream> #include<cst ...

  8. 集训作业 洛谷P1032 字串变换

    集训的题目有点多,先写困难的绿题吧(简单的应该想想就会了) 嗯,这个题看起来像个搜索呢(就是个搜索) 我们仔细想想就知道这个题肯定不能用深搜,可以优化的地方太少了,TLE是必然的. 那我们该怎么办呢? ...

  9. P1032 字串变换 字符串BFS

    题目描述 已知有两个字串A,BA,B及一组字串变换的规则(至多66个规则): A_1A1​ ->B_1B1​ A_2A2​ -> B_2B2​ 规则的含义为:在 AA中的子串 A_1A1​ ...

随机推荐

  1. MySQL事务笔记

    1.结束事务的方法用什么? 2.事务的最终形态是什么? commit 提交 rollback 回滚 3.事务的四大特征? ⑴ 原子性 一个事务是最小的工作单元,事务包含的所有操作要么全部成功,要么全部 ...

  2. c++中虚函数和多态性

    1.直接看下列代码: #include <iostream> using namespace std; class base{ public: void who(){ cout<&l ...

  3. T-SQL:开窗函数(十二)

    1.基本概念 开窗函数分为两个部分分别是 1.聚合,排名,偏移,分布函数 . 2.开窗分区,排序,框架. 下面举个例子 SELECT empid, ordermonth, val, SUM(val) ...

  4. Python知识梳理

    这是个人学习笔记,非教程,内容会有些混乱 极简教程     数据类型 我们可以使用type()函数类获取对象的类型,Python3中内置数据类型包括:None,int,float,complex,st ...

  5. 自定义滚动条mCustomScrollbar

    mCustomScrollbar 是个基于 jQuery UI 的自定义滚动条插件,它可以让你灵活的通过 CSS 定义网页的滚动条,并且垂直和水平两个方向的滚动条都可以定义,它通过 Brandon A ...

  6. 【Java】包,jar包的扫描

    包扫描在框架中应用很广泛,在spring中,通过给自己的类加注解的方式,利用spring的包扫描,完成依赖注入. package com.test.package_scanner.core; impo ...

  7. Java基础——Ajax(二)

    一.jQuery 实现 ajax $(function(){ $("#userName").blur(function(){ // 发ajax请求 用的函数原型: $.get(ur ...

  8. 后端自测必备神器-PostMan

    作为后端的一个小小菜鸟,写代码没有把握,总怕出错,也不敢直接扔测试,这个时候就需要一个神器能够辅助自己去测试各种情况,让自己安心的交给测试,嗯……这时神器出场了------PostMan.在一个偶然的 ...

  9. pom.xml复制过来的代码报错-Maven expected START_TAG or END_TAG not TEXT (positionTEXT se

    场景 编译器:IDEA 在网上看一些小实例,跟着做的时候会复制pom.xml文件的代码来加载依赖包.首先需要确定你复制过来的代码本身是没有错的,在复制一些pom.xml文件代码时,有时候会报错.原因是 ...

  10. How do I close a single buffer (out of many) in Vim?

    I open several files in Vim by, for example, running vim a/*.php which opens 23 files. I then make m ...