洛谷 P1032 字串变换
发布日期:2021-06-24 06:58:54 浏览次数:5 分类:技术文章

本文共 3016 字,大约阅读时间需要 10 分钟。

题目描述

已知有两个字串 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 xyzabc xuud yy 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 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
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
mp; //相当于vis 35 void bfs()36 {37 mp.clear();38 queue
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\n", mp[hw]); return;}55 }56 }57 }58 }59 printf("NO ANSWER!\n");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数组

 

转载于:https://www.cnblogs.com/mrclr/p/8410920.html

转载地址:https://blog.csdn.net/weixin_30896763/article/details/98798815 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:IOS之多媒体API
下一篇:指令创建 Express Node.js 项目

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月05日 13时20分26秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章