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

由于数据很水,这道题用不到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. [ABC262C] Min Max Pair

    Problem Statement You are given a sequence $a = (a_1, \dots, a_N)$ of length $N$ consisting of integ ...

  2. python tkinter 使用(七)

    python tkinter 使用(七) 本篇文章主要讲下tkinter 中的message 控件. Message控件可以用于在窗口中显示一段文本消息. 以下是个简单的例子: #!/usr/bin/ ...

  3. 【OpenCV】【Python】关于cv2.findContours()轮廓索引(编号)解析(RETR_TREE)

    在打算自己实现二维码的定位的时候,看到了相关博文的关于cv2.findContours返回的层级信息来定位三个"回"字从而达到定位二维码的目的,但是返回的hierarchy中的层级 ...

  4. ElasticSearch之cat thread pool API

    命令样例如下: curl -X GET "https://localhost:9200/_cat/thread_pool?v=true&pretty" --cacert $ ...

  5. ElasticSearch之cat plugins API

    命令样例如下: curl -X GET "https://localhost:9200/_cat/plugins?v=true&pretty" --cacert $ES_H ...

  6. Lean大神编译的OpenWRT问题汇总

    1.初始密码为password,登录路由器后第一件事要修改默认密码 2.Lean大神编译的OpenWRT无法SSH.SFTP, 3.为了方便操作,一定要编译的时候安装TTYD,但是TTYD默认无法打开 ...

  7. .net Core实战简单文件服务器

    首先新建一个ASP.NET Core 项目,选中空的模板,如下图所示 在NuGet包中添加Microsoft.AspNetCore.StaticFiles 添加好以后我们在Startup.cs中添加对 ...

  8. CSS3学习笔记-字体属性

    在CSS3中,可以使用字体属性来控制网页中文本的样式和排版.以下是常用的字体属性: font-family 该属性用于指定网页中的文本所使用的字体.我们可以通过使用通用的字体名称,或者直接使用字体名称 ...

  9. LeetCode LRU缓存机制

    146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...

  10. 云图说|应用魔方AppCube:揭秘码农防脱神器

    摘要: 应用魔方(AppCube)是华为云为行业客户.合作伙伴.开发者量身打造的一款低代码开发平台.通过AppCube可轻松构建专业级应用,创新随心所欲,敏捷超乎想象. 本文分享自华为云社区<云 ...