写这道不算难的题目是我遇到了不少问题,复述以下过程吧。

由于数据很水,这道题用不到KMP算法,只要使用朴素算法进行字符串比对就可以了。

1

首先,我错误的选择了dfs算法,导致了TLE的发生。这类求最优解的问题显然大多应该用bfs解决,可是改用bfs后依然不对。

2

过了一天,我我发现自己忘了考虑如果一个字符串多处都可以用同一规则替换,那么各处替换都应该考虑到的这一问题。最开始我都是只替换第一处的。后来意识到这一问题是我刚开始觉得如果每一处都有换和不换两种情况且有n处可换的话,我岂不是应该把2的n次方个元素插入队列?这样实现起来好麻烦,又不如深搜了。后来我意识到我并不需要插入2

的n次方个元素,我只需要插入n个就可以了,即分别是“第一处改其他都不改”、“第二处改其他都不改”、...、等等。因为那种”“第xy处改”的情况其实当只有第x处改的那个入队的元素出队的时候自然会考虑到,所以并不需要现在考虑那个问题。于是我解决了这一问题再然后,我发现依然TLE了,观看题解发现bfs竟然也要排重才可以,否则哪怕是bfs算法,不排重也会算的贼慢。排重自然是想到用了map,然而,使用map后五个点中有两个点RE,剩下三个点AC。我在本地ide中测试发现终端输出libc++abi: terminating due to uncaught exception of type std::out_of_range: basic_string,意思是抛出了一个out_of_range异常。我把map有关的查重代码注释掉之后就不在异常了,说明是查重代码if (m.find(tstr.s) != m.end()) {continue;}m[tstr.s]=1;导致了out_of_range异常的抛出,可我不理解为何如此已经该怎么修

3

过了一天,我出去玩了,又过了一天,我重新开始想这道题,我发现事实并非如我昨天想的那样,删除map有关代码就不再报错并不一定是因为map抛出了异常

,还有可能是map导致的代码执行的变化致使其他函数抛出了异常,自己之前的那个把罪直接定在map上的想法实在是太绝对了。事实上,是string抛出了异常,原因也很简单,我访问了越界的数据。在strf::can这个“判断s能否使用Vi规则进行替换”的函数时忘了Vi(a->b)规则的a有可能比s还长。我先入为主的认为了s应该是一个长串,导致了没想到这个问题。后来我使用输出中间变量的办法好久也没发现问题所在,直到用调试模式开始逐步调试的时候才发现了问题所在,然后加入了一行简单的判断代码就解决了这个问题。

教训

1、要慎重选用bfs还是dfs,最优解问题应该选用dfs,涉及输入过程的bfs和dfs都可以做到过程输出,更应该看需要输出一个过程还是所有过程,从而判断是bfs还是dfs。

2、别舍不得排重用到的空间,很多时候排重能带来很大的时间优化。

3、不能武断的判断抛出异常的对象。

4、涉及字符串和数组的每个部分都一定要考虑好是否越界。

5、应当更习惯使用调试程序来排错而非输出中间数据来排错。

最终代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <stack>
#include <vector>
#include <cmath>
#include <map>
#include <queue> using namespace std; struct strf
{
string a,b;
strf(string x,string y){a=x;b=y;}
int can(string s,int pass)
{
if(s.length()<a.length()) return -1;
for(int i=0;i<=s.length()-a.length();i++)
{
int flag=1;
for(int j=i;j<=i+a.length()-1;j++)
{
if(s[j]!=a[j-i])
{
flag=0;
break;
}
}
if(flag==1)
{
if(pass==0)
return i;
else
pass--;
}
}
return -1;
}
string doit(string s,int pos)
{
string tail=s.substr(pos+a.length());
s.erase(pos,s.length()-pos); s+=b; s+=tail;
return s;
}
};
struct str{string s;int step;str(string S,int Step){s=S;step=Step;}}; vector<strf> V;//其实可以换成链表来存储,在这个特定需求下,很适合用链表
string A,B,s1,s2;
queue<str> q;
map<string,int> m; int main()
{
cin>>A>>B;
while(cin>>s1>>s2)
V.push_back(strf(s1,s2));
q.push(str(A,0));
while(!q.empty())
{
str tstr(q.front()); q.pop();
if(tstr.step>10)break;
if(tstr.s==B){cout<<tstr.step<<endl;return 0;}
if (m.find(tstr.s) != m.end()) {continue;} m[tstr.s]=1;
for(int i=0;i<V.size();i++)
for(int pass=0;V[i].can(tstr.s,pass)!=-1;pass++)
q.push(str(V[i].doit(tstr.s,V[i].can(tstr.s,pass)),tstr.step+1));
}
cout<<"NO ANSWER!"<<endl;
return 0;
}

P1032的更多相关文章

  1. 洛谷 P1032 子串变换

    题目链接 https://www.luogu.org/problemnew/show/P1032 本题是一道bfs问题,从a串开始,每一步完成替换一对字符串(但是一个一步替换可以将这对字符串替换好几次 ...

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

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

  3. 【题解】洛谷P1032 [NOIP2002TG]字串变换(BFS+字符串)

    洛谷P1032:https://www.luogu.org/problemnew/show/P1032 思路 初看题目觉得挺简单的一道题 但是仔细想了一下发现实现代码挺麻烦的 而且2002年的毒瘤输入 ...

  4. 洛谷 P1032 [ NOIP 2002 ] 字串变换 —— 字符串+bfs

    题目:https://www.luogu.org/problemnew/show/P1032 字符串好复杂...先写了个 dfs ,RE一个点TLE一个点,不知该怎么改了... #include< ...

  5. 洛谷 P1032 字符变换

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

  6. 洛谷 P1032 字串变换题解

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

  7. 【洛谷】P1032 字串变换

    题目地址:https://www.luogu.org/problemnew/show/P1032 洛谷训练场BFS的训练题呀. “BFS不就是用队列的思想去遍历一切情况嘛.我已经不是小孩子了,我肯定能 ...

  8. luogu题解P1032字串变换--BFS+STL:string骚操作

    题目链接 https://www.luogu.org/problemnew/show/P1032 分析 这题本来很裸的一个BFS,发现其中的字符串操作好烦啊.然后就翻大佬题解发现用STL中的strin ...

  9. TYVJ P1032 零用钱 Label:贪心

    背景 USACO OCT09 7TH 描述 作為创造產奶纪录的回报,Farmer John决定开始每个星期给Bessie一点零花钱. FJ有一些硬币,一共有N (1 <= N <= 20) ...

  10. P1032 字串变换

    最近在练习bfs,看到了02年提高组的这个题,顿时来了兴致,联想到前一阵子的八数码问题,具体就是使用一个字符串来存储状态,把他存储到一个图中,然后开始bfs,如果10步之内无法完成就剪枝,同时使用哈希 ...

随机推荐

  1. STL常用函数

    STL简介 \(STL\)是\(Standard\) \(Template\) \(Library\)的简称,中文名称为标准模板库,从根本上讲, 就是各种\(STL\)容器的集合,容器可以理解为能够实 ...

  2. NVIDIA RTX4090,你能用它做什么?

    都说男生是世界上最简单的动物,为什么呢?举个例子,你要给女朋友送礼,你可以选择包.口红.护肤品.化妆品等,而包的品牌和样式.口红的色号等足以让你挑得眼花缭乱.而男生不一样,如果女生选择给男生送礼,我相 ...

  3. 如何将Swagger接口导入ApiFox

    先按照如下图操作 在apifox创建一个新项目,点击项目 点击导入数据(可以选择手动或者自动) 复制刚才的url,然后立即导入,保存

  4. 使用vLLM和ChatGLM3-6b批量推理

    当数据量大的时候,比如百万级别,使用 ChatGLM3-6b 推理的速度是很慢的.发现使用 vLLM 和 ChatGLM3-6b 批量推理极大的提高了推理效率.本文主要通过一个简单的例子进行实践. 1 ...

  5. System类的方法

    1.exit() 2.currentTimeMills() 代码练习

  6. 玩转Python:处理音频文件,两个非常重要的库,很实用,附代码

    pyaudio和sounddevice都是用于Python中音频处理和流的库,允许用户通过他们的API录制.播放和处理音频数据.下面是对这两个库的简要介绍: PyAudio PyAudio 提供了 P ...

  7. Supershell防溯源反制配置

    简介 项目地址:https://github.com/tdragon6/Supershell Supershell是一个集成了reverse_ssh服务的WEB管理平台,使用docker一键部署(快速 ...

  8. LeetCode 947. 移除最多的同行或同列石头 并查集

    传送门 思路 干货太干就不太好理解了,以下会有点话痨( ̄▽ ̄)" 首先题目给了一个二维stones数组,存储每个石子的坐标,因为在同行或者同列的石子最终可以被取到只剩下一个,那么我们将同行同 ...

  9. 中秋节,华为云AI送上超级大月亮制作教程,体验赢开发者键鼠套装

    摘要:一键"Run in ModelArts",无需考虑计算资源.环境的搭建,简单运行代码,即可拥有你的超级大月亮,打造专属于你的梦幻中秋月夜. 本文分享自华为云社区<中秋节 ...

  10. openGauss内核:简单查询的执行

    摘要:本文主要分析简单查询语句在业务处理线程Postgres上的执行流程,并介绍如何利用gdb梳理代码逻辑. 本文分享自华为云社区<openGauss内核分析(二):简单查询的执行>,作者 ...