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

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

    题目链接 考虑最后形态,一定是有某一个区间 \([l,r]\) 保持初始的样子, \(l\) 前面都是 <,\(r\) 后面都是 >. 这个区间一定是某两个相邻圆点的位置.设 \(f_i\ ...

  2. NTP时间服务器优先级介绍

    先思考一个问题:当一个客户端配置向多个NTP时间服务器校时,此时客户端优先向哪个时间服务器同步时间呢? 一个完整的NTP校时请求分四步: 1.客户端向服务器发起校时请求 2.服务器收到客户端发送的校时 ...

  3. 山海鲸Cesium:用更简单的方式升级视效

    CesiumJS作为绝大多数人都在用的开源地球可视化引擎,视觉效果并不拔尖,这让很多giser都想着有一天升级一下视效,从众多平庸的项目中脱颖而出.然而,对于一些使用Cesium的项目来说,要想达到C ...

  4. libGDX游戏开发之Sprite、Texture和TextureRegion绘制旋转、反转(九)

    libGDX游戏开发之Sprite.Texture和TextureRegion绘制反转(九) libGDX系列,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm- ...

  5. Java程序接入ChatGPT

    目录 0 前言 1 还想体验的小伙伴可以试试 2 Java接入前准备 3 官方支持接入语言 4 调用费用 5 接口调用说明 6 代码实现 6.1 postman调用 6.2 Java调用 7 小结 0 ...

  6. 最新系统MacOs13 Ventura(M1/M2芯片) + Parallels Desktop 18(PD18史上最强虚拟机)永久使用攻略

    众神殿内,高朋满座,胜友如云,Vmware.VirtualBox.Utm等虚拟机大神群英荟萃,只见位于C位王座上的Parallels怅惘抬头,缓缓逡巡,睥睨群小,目光到处,无人敢抬头对视. 是的,如果 ...

  7. 玩转云上数据湖,解析Serverless 技术落地

    导读: 本文主要介绍Serverless计算相关技术与其在华为云数据湖探索服务(后文简称DLI)中的技术落地.Serverless是DLI将计算能力服务化和产品化关键技术,与传统IAAS和PAAS技术 ...

  8. 2种GaussDB(DWS)查看作业运行信息方式

    摘要:提供以作业基本单位的作业统计视图pgxc_session_wlmstat,便于用户观察运行作业和排队作业信息. 本文分享自华为云社区<GaussDB(DWS)如何查看作业运行信息>, ...

  9. 华为云GaussDB坚持技术引领,以数字化转型激活金融科技新动能

    摘要:"银行业数字化转型实践交流会"杭州站顺利收官. 由华为与北京先进数通联合主办的"银行业数字化转型实践交流会"杭州站顺利收官,会议邀请了金融科技先锋企业.机 ...

  10. Rust太难?那是你没看到这套Rust语言学习万字指南!

    摘要:从开发环境.语法.属性.内存管理和Unicode等五部分,为你带来一份详细的Rust语言学习的精华总结内容. 一.Rust开发环境指南 1.1 Rust代码执行 根据编译原理知识,编译器不是直接 ...