• 洛谷 P1032 字串变换


    题目描述

    已知有两个字串 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
     
    差不多是一道水题吧。。就是 bfs 暴搜就行。只不过在搜的时候要注意以下几点:
    1.每一次是如何变换的
     1 string change(const string& now, int st, int num)    //now字符串第st位,第num条变换规则 
     2 {
     3     for(int i = 0; i < a1[num].length(); ++i)    
     4     {
     5         if(st + i >= now.length()) return "";      //若超出原字符串长度或 
     6         if(now[st + i] != a1[num][i]) return "";  //有一位不符合规则,就不能变换,返回空字符串 
     7     }
     8     string ret;
     9     //变换分三步 
    10     for(int i = 0; i < st; ++i) ret += now[i];//1.将原字符串不用变换的前半部分复制下来 
    11     ret += b1[num];                 //2.再加上变换部分 
    12     for(int i = st + a1[num].length(); i < now.length(); ++i) ret += now[i];//3.加上原字符串剩下部分 
    13     return ret;
    14 }

    用 string 的好处是,它支持加减运算,就是增加或减去某一字符串,而不用库里的 strcpy 函数。

    2.再用bfs时,要记录之前的状态,防止又退回去,进入死循环。但这道题开 vis 数组就不太合适,因为每一个状态是一个字符串。所以最好开一个 map 来记录状态,并判重。

    3.若按 2 的方法,因为是字符串的操作,大数据可能会超时,所以可以将字符串编码为 unsigned long long,一个简单的hash

    1 ull hash(const string& now){
    2     ull ret = 0;
    3     for (int i = 0; i < now.length(); i++){
    4         ret += now[i] - 'a' + 1; ret *= 27;
    5     }
    6     return ret;
    7 }

    完整代码

     1 #include <cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<map>
     8 using namespace std;
     9 typedef unsigned long long ull;
    10 const int maxn = 25;
    11 string a, b;
    12 string a1[8], b1[8];
    13 int cnt = 0;
    14 ull hash(const string& now){
    15     ull ret = 0;
    16     for (int i = 0; i < now.length(); i++){
    17         ret += now[i] - 'a' + 1; ret *= 27;
    18     }
    19     return ret;
    20 }
    21 string change(const string& now, int st, int num)
    22 {
    23     for(int i = 0; i < a1[num].length(); ++i)
    24     {
    25         if(st + i >= now.length()) return "";
    26         if(now[st + i] != a1[num][i]) return "";
    27     }
    28     string ret;
    29     for(int i = 0; i < st; ++i) ret += now[i];
    30     ret += b1[num]; 
    31     for(int i = st + a1[num].length(); i < now.length(); ++i) ret += now[i]; 
    32     return ret;
    33 }
    34 map<ull, int>mp;    //相当于vis 
    35 void bfs()
    36 {
    37     mp.clear();
    38     queue<string>q;
    39     q.push(a); mp[hash(a)] = 0;
    40     while(!q.empty())
    41     {
    42         string now = q.front(); q.pop();
    43         ull hn = hash(now);
    44         if(mp[hn] >= 10) break;
    45         for(int i = 0; i < cnt; ++i)
    46         {
    47             for(int j = 0; j < now.length(); ++j)
    48             {
    49                 string neww = change(now, j, i);
    50                 ull hw = hash(neww);
    51                 if(neww != "" && mp.find(hw) == mp.end())
    52                 {
    53                     q.push(neww); mp[hw] = mp[hn] + 1;
    54                     if(neww  == b) {printf("%d
    ", mp[hw]); return;}
    55                 }
    56             }
    57         }
    58     }
    59     printf("NO ANSWER!
    ");
    60 }
    61 int main()
    62 {
    63     cin >> a >> b;
    64     while(cin >> a1[cnt] >> b1[cnt]) cnt++;
    65     bfs();
    66     return 0;
    67 }

    值得一提的是,这里的 map 发挥了两个作用,一个是 vis 数组,另一个是相当于记录步数的 dis数组

  • 相关阅读:
    寻找jar包的方法
    mysql使用小技巧
    JavaSe基础知识总结
    JavaScript进阶和JQuery入门
    Day03 JavaScript入门
    Day02 CSS样式
    Day01-HTML
    Redis详解
    关于开发的包
    关于.Net WebAPI数据认证(包括登陆认证、模型认证)
  • 原文地址:https://www.cnblogs.com/mrclr/p/8410920.html
Copyright © 2020-2023  润新知