P1032 [NOIP2002 提高组] 字串变换题解(迭代优先搜索+剪枝+记忆化搜索)

博客探讨了字符串操作如replace在C++中的应用,并通过一个子串变换问题展示了迭代加深搜索结合剪枝和记忆化搜索的实现。博主在解决过程中遇到了函数使用和搜索策略的挑战,最终成功解决了问题。此外,还提到了双向BFS作为另一种解决方案。
摘要由CSDN通过智能技术生成

思路:
子串变换,本题打算先用迭代加深搜索来做,然后的话加上一个map判重剪枝。(这题重点是练一下字符串函数,很少做字符串的搜索题)

string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos,也就是-1。(map用过)

#include<iostream>
using namespace std;
int main()
{
    string str1="She drinks too much!";
    str1=str1.replace(str1.begin(),str1.begin()+3,"He");
    cout<<str1<<endl;//原串从下标为0数的3个字符She用He替换

    string s="Hello!c";
    char c='h';
    s=s.replace(0,6,5,c);//原串从下标为0的6个字符用5个字符h替换
    cout<<s<<endl;

    string str2="Good morning! Enjoy youself!";
    string s2="A good evening..";
    str2=str2.replace(5,8,s2,7,9);//s2从下标7开始的9个字符来替换s1从下标5开始的8个字符
    cout<<str2<<endl;
    return 0;
}

改题该题原本想用map存储组合,但后来发现容易有冲突,所以又改成了string字符串数组,直接string s[3]就好了。

#include<cstdio>
#include<iostream>
#include<map>
#include<cstring>
using namespace std;
string book1[7],book2[7];
map<string,int> mark;
string bgi,edi;
int top=0;
bool sus=0;
void dfs(string cur,int step,int maxn){
	
    if(step==maxn){(满足到达的深度数就退出)
        if(cur==edi)sus=1;
        return ;
    }
    
    if(sus)return ;
    
    if(mark[cur]!=0&&step>=mark[cur])return ;(记忆化剪枝,要是当前是处在同一层搜索区域内撞上了就返回(因为之前有比它小的,肯定之前的状态怎样都会比它小))
    mark[cur]=step;
    
    for(int i=1;i<=top;i++){
        string now=book1[i];
        int k=0;
        int loc=cur.find(now,0);(这里有个坑,就是它只会找第一个,加个for循环全部试一遍!)
        for(;loc!=cur.npos;loc=cur.find(now,k)){
        	k=loc+1;(记录下一个位置)
        	
        	string temp=cur;
        	string tem=cur.replace(loc,now.length(),book2[i]);
        	cur=temp;(注意:cur也会发生改变,要备份一下)
        	
        	dfs(tem,step+1,maxn);
        }
    }

}
int main(){
    cin>>bgi>>edi;
    mark[bgi]=1;
    string a,b;

    while(top<6&&cin>>a>>b){(输入没有结束,cin就返回为真,否则的话返回为假)
        top++;
        book1[top]=a;
        book2[top]=b;(这里不能用map,因为会有冲突)
    }
    
    for(int maxd=0;maxd<=10;maxd++){(迭代加深搜索)
        dfs(bgi,0,maxd);
        mark.clear();(这里记得clear一下,不然的话后面的搜索会被前面的所制约住(因为他们找的路径是一样的,这种情况下很容易满足剪枝条件))
        if(sus){
            printf("%d",maxd);
            return 0;
        }
    }
    printf("NO ANSWER!");
}

总结:看着似乎很简单其实一堆坑,例如函数的使用(自己不熟)、以及途中搜索之类的,这题除了用迭代加深搜索+剪枝+记忆化搜索可以做出来之外,还可以用双向BFS,具体的放在另外一个题解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值