首页 > 其他分享 >双向广搜->字符变换(洛谷P1032)

双向广搜->字符变换(洛谷P1032)

时间:2024-01-10 12:12:35浏览次数:24  
标签:qs 洛谷 int P1032 bfs rules qe 双向 front

题意:给起始和终止串A和B,以及不超过6个字符串变换规则,求A->B能否在10步以内变换完成。

分析:暴力bfs每次有6条路可以走,时间复杂度是6^10 大概6e8的时间复杂度,会TLE。于是这题是一道经典的双向bfs。 直接开两个队列,两个map,暴力搜1~5步即可。
双向bfs的时间复杂度是2 * (6 ^ 5) = 1e4级别。所以双向bfs在指数级增长的搜索中优势巨大。

'

void solve(){
    string a, b;
    cin >> a >> b;

    vector<pair<string, string>> rules(1);
    //int t = 1;
    while (cin >> rules[0].first >> rules[0].second){
        rules.emplace_back(rules[0]);
       // t ++;if (t > 3) break;
    }
    int rule_size = int(rules.size()) - 1;

    map<string, bool> go;
    map<string, bool> come;
    queue<pair<string, int>> qs, qe;
    qs.emplace(a, 0);
    qe.emplace(b, 0);
    go[a] = true;
    come[b] = true;

    auto bfs = [&]()->int{
        while (!qe.empty() || !qs.empty()){
            int now = qs.front().second;
            if (now >= 5){
                break;
            }
            while (!qs.empty() && qs.front().second == now){
                auto[s, cur] = qs.front();
                qs.pop();
                for (int i = 1; i <= rule_size; ++i){
                    for (int j = 0; j < int(s.size()); ++j){
                        if (s.find(rules[i].first, j) == s.npos){
                            break;
                        }
                        auto tmp_s = s;
                        tmp_s.replace(tmp_s.find(rules[i].first, j), int(rules[i].first.size()), rules[i].second);
                        if (!go.count(tmp_s)){
                            if (come.count(tmp_s)){
                                return (now + 1) * 2 - 1;
                            }
                            qs.emplace(tmp_s, now + 1);
                            go[tmp_s] = true;
                        }
                    }
                }
            }

            now = qe.front().second;
            if (now > 5){
                break;
            }
            while (!qe.empty() && qe.front().second == now){
                auto[s, cur] = qe.front();
                qe.pop();
                for (int i = 1; i <= rule_size; ++i){
                    for (int j = 0; j < int(s.size()); ++j){
                        if (s.find(rules[i].second, j) == s.npos){
                            break;
                        }
                        auto tmp_s = s;
                        tmp_s.replace(tmp_s.find(rules[i].second, j), int(rules[i].second.size()), rules[i].first);
                        if (!come.count(tmp_s)){
                            if (go.count(tmp_s)){
                                return (now + 1) * 2;
                            }
                            come[tmp_s] = true;
                            qe.emplace(tmp_s, now + 1);
                        }
                    }
                }
            }
        }
        return -1;
    };



    int ans = bfs();
    if (ans == -1){
        cout << "NO ANSWER!" << '\n';
    }
    else{
        cout << ans << '\n';
    }

}

'

标签:qs,洛谷,int,P1032,bfs,rules,qe,双向,front
From: https://www.cnblogs.com/yxcblogs/p/17956210

相关文章

  • 双向广搜-> hdu1195
    问题描述:密码锁有起始和目标两个状态,状态有4个连续数字,数字范围是1~9。其中特殊情况9+1=0,1-1=9。每次操作可以交换相邻的两个锁上的数字,或者将该位上数字±1。求最小操作次数分析:是一道双向广搜的题,但是这个题目的第一个思路就是枚举所有的排列组合状态,然后对每个状......
  • 洛谷 P7409 SvT
    洛谷传送门考虑对反串建SAM,设\([i,n]\)的后缀对应SAM的点是\(a_i\)。那么\(\text{lcp}(s[i:n],s[j:n])=\text{len}(\text{lca}(a_i,a_j))\)。于是问题变成了,给定一些点,统计两两\(\text{lca}\)点权之和。考虑建虚树,枚举每个点\(u\)作为\(\text{lca}\)的......
  • 数据结构线性表之【循环链表、双向链表】
    循环链表在单链表中,每个结点都带有一个指向其后继结点的指针,但因为表尾元素没有后继结点,所以表尾结点的指针域为空,表明它不指向任何结点,并表示这个结点是最后一个结点。现在修改这个约定,将表尾结点的指针指回头结点,从而形成一类新链表。在这样的链表中,从任何一个结点出发并沿着指针......
  • 临沂城建“做媒”,中国女排与沂蒙大地“双向奔赴”
    来源:体育行业网2023年10月7日,杭州亚运会上,中国女排3比0战胜日本女排夺得冠军,第九次站在亚运会最高领奖台。摧枯拉朽般的胜利,值得所有人的掌声和欢呼,这其中来自沂蒙老区人民的呐喊尤为响亮。同年12月25日下午,国家体育总局排球运动管理中心副主任袁磊宣布,2024年排球超级联赛全明星系......
  • 洛谷火柴人
    importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.io.StreamTokenizer;publicclassMain{staticintn;staticintnumber=0;staticint[]arr=newint[20000];staticboolean[]st=newboolean[20000];sta......
  • 【史上最本质】序列模型:RNN、双向 RNN、LSTM、GRU、Seq-to-Seq、束搜索、Transformer
    序列模型:RNN、双向RNN、LSTM、GRU、Seq-to-Seq、束搜索、Transformer、Bert序列模型是啥RNN结构双向RNN长短期记忆递归神经网络LSTM门控循环单元GRU编码器-解码器Seq-to-SeqBeamSearch束搜索:选择最佳翻译结果TransformerBert 序列模型是啥序列数据是,按照时间顺序或者某......
  • 【史上最小白】Bert 分析类大模型:双向 Transformer 编码器
    Bert:双向Transformer编码器Bert:论洞察语境,GPT不如我深刻;论理解含义,ELMo不如我全面输入阶段词嵌入:把词语转换为向量第一个预训练Masked:学习语言的深层次理解尝试1:预测每个单词尝试2:Masked语言模型尝试3:用随机单词替换部分遮住的单词尝试4:结合遮盖、随机替换和不变的单词......
  • 【C++】STL 容器 - list 双向链表容器 ② ( list 常用 api 简介 | 首尾 添加 / 删除
    文章目录一、元素操作1、首尾添加/删除元素2、获取首尾元素二、迭代器遍历容器1、正向迭代与反向迭代2、代码示例一、元素操作1、首尾添加/删除元素list双向链表容器提供了push_back、pop_back、push_front和pop_front等一系列用于操作列表元素的成员函数,函......
  • 【C++】STL 容器 - list 双向链表容器 ① ( 容器特点 | 容器操作时间复杂度 | 构造函
    文章目录一、list双向链表容器简介1、容器特点2、容器操作时间复杂度3、遍历访问5、头文件二、list双向链表容器构造函数1、默认无参构造函数2、创建包含n个相同元素的list双向链表3、使用初始化列表构造list双向链表4、使用另外一个list容器构造list双向链表容器......
  • 【C++】STL 容器 - list 双向链表容器 ③ ( list 常用 api 简介 | 中间位置 插入 / 删
    文章目录一、list双向链表容器的中间位置插入元素1、在指定位置插入1个元素-insert函数2、在指定位置插入n个相同元素-insert函数3、中间位置插入另一个容器的指定范围内的元素-insert函数二、list双向链表容器的中间位置删除元素1、删除容器中所有元素......