字串变换-------------------------双向广搜(BFS优化+针对最小步数模型)

已知有两个字串 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

解析:
双向广搜一般应用于最小步数模型
每次选择队列中数量较小的一部分,以达到平衡

#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int n;
int step;
string a[N],b[N];
int extend(queue<string> &q,unordered_map<string,int> &da,unordered_map<string,int> &db,string a[],string b[])
{
    auto t=q.front();
    q.pop();
    for(int i=0;i<t.size();i++)//枚举t串的每个部分,看是否能被替换
    {
        for(int j=0;j<n;j++)//枚举替换的部分
        {
            if(t.substr(i,a[j].size())!=a[j]) continue;
            string r=t.substr(0,i)+b[j]+t.substr(a[j].size()+i);//找到了可以替换的地方,那么我们需要截取t串下标为0,长度i+替换的部分+后面剩余的部分
            if(db.count(r)!=0) return db[r]+1+da[t];//如果r这个状态存在的话db中,那么我们就需要返回db[r]+1+da[t](解释:db[r]搜到r的步数。da[t]+1:t这个状态转换为r这个状态所以需要+1)
            if(da.count(r)) continue;//如果r状态再da出现过就不需要了
            da[r]=da[t]+1;//距离+1
            q.push(r);//入队
        }
    }
    return -1;
}
int bfs(string A,string B)
{
    unordered_map<string,int> da,db; //设置双向
    queue<string> qa,qb; //初始化
    qa.push(A);
    da[A]=0;
    qb.push(B);
    db[B]=0;
    while(qa.size()&&qb.size())
    {
        int t;
        if(da[qa.front()]+db[qb.front()]>10) return 11;//如果两个方向所搜到的状态,都无法在图上连通,且两个方向上的步数和大于10,则不满足。
        if(qa.size()<=qb.size()) t=extend(qa,da,db,a,b);//因为是双向,每次去队列数量较小的一面,以致达到平衡
        else t=extend(qb,db,da,b,a);
        if(t!=-1) return t;
    }
    return 11;
}
int main()
{
    string A,B;
    cin>>A>>B;
    while(cin>>a[n]>>b[n]) n++;
    step=bfs(A,B);
    if(step>10) puts("NO ANSWER!");
    else printf("%d\n",step);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
字串转换 a->b, b->c,意思是将字符串中的 “a” 替换成 “b”,再将字符串中的 “b” 替换成 “c”。例如,将字符串 “abbabc” 转换成 “bccabc”。 这是一种字符串操作,可以使用循环和条件语句来实现。首先,需要遍历字符串中的每个字符,判断是否为 “a” 或 “b”。如果是 “a”,就将其替换成 “b”;如果是 “b”,就将其替换成 “c”。然后再将新字符串存储下来,最后输出即可。 下面是具体的实现过程: 1. 定义一个字符串 str,保存要转换的字符串; 2. 定义一个空字符串 result,保存转换后的字符串; 3. 使用 for 循环遍历字符串。for 循环的语法是: ``` for (var i = 0; i < str.length; i++) { // ... } ``` 其中,i 是循环变量,从 0 开始,每次加 1,直到 i 等于字符串的长度为止。 4. 在循环中,使用 if 语句判断当前字符是 “a” 还是 “b”。if 语句的语法是: ``` if (str[i] === "a") { // ... } else if (str[i] === "b") { // ... } ``` 其中,str[i] 表示字符串中第 i 个字符,=== 表示恒等于,注意使用双引号将字符包裹住。 5. 如果字符是 “a”,将其替换成 “b”;如果是 “b”,将其替换成 “c”。可以使用字符串的 replace() 方法来实现替换。replace() 方法的语法是: ``` str.replace(原字符串, 替换成的字符串) ``` replace() 方法将返回一个新字符串,需要将其保存到 result 变量中。 6. 循环结束后,将 result 变量输出即可。 完整的代码如下: ``` var str = "abbabc"; var result = ""; for (var i = 0; i < str.length; i++) { if (str[i] === "a") { result += "b"; } else if (str[i] === "b") { result += "c"; } } console.log(result); // 输出 "bccabc" ``` 此代码实现了将字符串中的 “a” 替换成 “b”,再将 “b” 替换成 “c”,输出转换后的字符串。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值