zoukankan      html  css  js  c++  java
  • 字串变换

    原题链接:https://www.luogu.org/problem/show?pid=1032#sub

    很奇怪,莫名其妙就A掉了。。。真神奇2333

    洛谷红名留念。我会继续努力。

    题意已经把做法写得特别露骨了。。。最小步数,最多6个变换规则。。。。广搜自不必说,不仅可以寻找解而且还能判断步数(根据广搜首解最优的性质可以得到)。

    开两个数组记录串的转换关系,然后以a串(原串)为起点开始搜索,搜索目标是b串。

    需要一个map记录某个串是不是被搜到过,如果已经搜过了就不再继续搜 。

    我们枚举当前队列中队头那个串的每一个位置,对每一个位置枚举所有可能的转换手段,然后去尝试拼接。

    拼接函数借鉴了一下楼上stdcall大爷题解的思路,对于一个试图要改变的串str,我们试图在它的第i位用第j种手段改变,首先判断是否可行,然后再逐位拼接。并且如果拼接出的串是合法的,那么我们就把这个串继续压入队列,再次搜索,中间记录一下步数step和ans。

    最后输出ans时判断,如果ans超过了步数限制直接输出无解,否则输出步数。

    不过我发现,ans等于0时应该也是无解,这样会导致如果用ans<=10来判断是不是超出步数会WA掉第三个点。。

    参考代码:

     1 #include <iostream>
     2 #include <string>
     3 #include <cstring>
     4 #include <queue>
     5 #include <map>
     6 #define maxn 15
     7 using namespace std;
     8 struct node{//方便搜索,也可以使用pair简化
     9     string str;
    10     int step;
    11 };
    12 
    13 string a,b;
    14 string orginal[maxn];
    15 string translated[maxn];
    16 int n,ans;
    17 map<string,int> ma;//很重要的东西,用来判重,否则会TLE在第3点和第5点
    18 
    19 string trans(const string &str,int i,int j){//借鉴了stdcall大爷的思想
    20     string ans = "";
    21     if (i+orginal[j].length() > str.length())
    22         return ans;
    23 
    24     for (int k=0; k < orginal[j].length();k++)
    25         if (str[i+k] != orginal[j][k])
    26             return ans;
    27 
    28     ans = str.substr(0,i);
    29     ans+=translated[j];
    30     ans+=str.substr(i+orginal[j].length());
    31     return ans;
    32 }
    33 
    34 void bfs(){//一个平淡无奇的bfs过程
    35     queue <node> q;
    36     node s;
    37     s.str = a;
    38     s.step = 0;
    39     q.push(s);
    40 
    41     while (!q.empty()){
    42         node u = q.front();
    43         q.pop();
    44         string temp;
    45 
    46         if(ma.count(u.str) == 1) //剪枝,判断重复的路径
    47             continue;
    48 
    49         if (u.str == b){
    50             ans = u.step;
    51             break;
    52         }
    53         ma[u.str] = 1;
    54         for (int i=0;i < u.str.length();i++)//枚举当前串所有可能位置
    55             for (int j=0; j<n; j++){//枚举所有可能手段
    56                 temp = trans(u.str,i,j);
    57                 if (temp != ""){
    58                     node v;
    59                     v.str = temp;
    60                     v.step = u.step+1;
    61                     q.push(v);
    62                 }
    63             }
    64     }
    65     if (ans > 10 || ans == 0)
    66         cout << "NO ANSWER!" << endl;
    67     else
    68         cout << ans << endl;
    69 
    70 }
    71 
    72 int main(){
    73     cin >> a >> b;
    74     while (cin >> orginal[n] >> translated[n])
    75         n++;
    76     bfs();
    77     return 0;
    78 }
  • 相关阅读:
    Spring事务管理学习笔记
    写给初学前端工程师的一封信
    angularjs 自定义指令弹窗
    ng-if和ng-show的区别
    前端遇到的一些坑
    浏览器样式兼容总结
    百分比控制表格列宽,不起效
    ng-model 将时间戳转换为标准时间
    使用git和sourcetree提交代码的一些问题
    本地运行angularjs应用,提示出现跨域问题
  • 原文地址:https://www.cnblogs.com/OIerShawnZhou/p/7554976.html
Copyright © 2011-2022 走看看