题目描述

已知有两个字串 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. openssl rsautl和openssl pkeyutl(文件的非对称加密)

    openssl系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html rsautl是rsa的工具,相当于rsa.dgst的部分功能集合,可用于生成 ...

  2. centos7指定yum安装软件路径

    网上的命令都是垃圾 yum -c /etc/yum.conf --installroot=/opt/all_venv/ --releasever=/ install nginx 该命令简单解释如下: ...

  3. 所生成项目的处理器架构“MSIL”与引用“Microsoft.AspNet.Scaffolding.12.0, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=x86”的处理器架构“x86”不匹配。

    生成成功后: 3>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1820,5): ...

  4. bootstrap-multiselect 多选

    官方教程 http://www.kuitao8.com/demo/20140224/1/bootstrap-multiselect-master/index.html 使用方法: 第一步引用样式以及相 ...

  5. C# if---else---练习题整理

    if    else    语句是到今天为止学习的第一个完整的语句,把有意思的练习题整理下来开一下脑洞!!! 练习一简单的人工智能 1 static void Main(string[] args) ...

  6. ubuntu安装docker以及基本用法

    ubuntu安装docker以及基本用法 一.安装 安装前先更新apt-get源到最新版本 apt-get update 使用ubuntu自带的docker安装包安装docker apt-get in ...

  7. 初学CSS-3-文字的属性

    文字样式属性: 格式:font-style:italic;/normal; 快捷键:fsi / fsn + tab键 文字粗细属性: 格式:font-weight:bold;/bolder;/ligh ...

  8. InheritParasitic.js

    // 寄生式继承 // 其基本思路是类似创建对象时的工厂模式,将继承过程封装在一个函数里,然后返回一个对象 function createObject(o){ var clone = Object.c ...

  9. Python 字符串的操作

    字符串的拼接 a = "hello" b = "klvchen" c = a + b print(c) 结果: helloklvchen 注意:该方法效率比较低 ...

  10. loadsh常用函数

    此篇文章会记录常用的lodash函数 防抖函数:_.debounce() 创建一个去缓冲函数,该函数将自上次调用函数以来经过设置的等待毫秒后调用func. 去缓冲函数带有一个取消方法来取消延迟的fun ...