-
[1307] English Magic
- 时间限制: 2000 ms 内存限制: 65535 K
- 问题描述
-
XP's English is very poor! He will read A into ah! Now he needs you to do him a favor! Now he gives you two same length string s1 and s2, and you should use some rules change s1 into s2
Each time, you can add or minus 1 to any character.( When add 1 to 'z', the character will change to be 'a' and when minus 1 to 'z', the character will change to be 'a')
You can also exchange the character with its neighbor. Each action will take one step. Now your task is to tell XP the minimal steps to transform. - 输入
-
There are many cases.
Each test case contain two strings s1 and s2.It guarantee s1's length equal to s2's length and the length of the string will not exceed 5. - 输出
-
For each test case, print the minimal steps in one line
- 样例输入
-
aaa bbb aoxz oaxa
- 样例输出
-
3 2
- 提示
-
The first case:aaa->baa->bba->bbb The second case: aoxz->oaxz->oaxa
- 来源
-
加多宝凉茶
- 操作
- hnust_xiehonghao
给你两个长度相同的小写字母字符串(长度不超过 5),你可以对第一个字符串进行以下操作:
1.交换相邻两个字母。
2.对其中一个字母进行加一操作。(z 加一为 a)
3.对其中一个字母进行减一操作。(a 减一为 z)
求第一个字符串需要几次操作才能变成第二个字符串。思路:
BFS
一个状态代表从字符串一只经过交换操作得到的字符串以及其所需要的操作数。
接下去把第一个字符串入队。
每从队列中获取一个状态我们都做如下操作:
1.对于这个状态,它的步数就是状态中的步数加上每个字母只通过加减操作得到目标串的步数。
2.将这个状态的各位置相邻字母交换,每种位置交换得到一个新状态,当前步数加一,然后入队。
然后对于每次生成新状态,都检验一下这个状态的字符串是否已经出现过,若没出现过则可以不入队了。
#include<stdio.h> #include<string> #include<string.h> #include<math.h> #include<queue> #include<map> using namespace std; char s1[10],s2[10]; struct haha { string str; int step; }temp,q; int ans,len; map<string,bool>mp; int mmin(int a,int b) { if(a>b) return b; return a; } int dis(string &p)//求2字符串进行字符加1减1操作需要进行的次数 { int cnt=0,i; for(i=0;i<len;i++) { int mid=abs(p[i]-s2[i]); mid=mmin(mid,26-mid); cnt+=mid; } return cnt; } void BFS() { int i,j; q.step=0; q.str=s1; queue<struct haha> que; que.push(q); while(!que.empty()) { temp=que.front(); que.pop(); if(ans<=temp.step) continue; ans=mmin(ans,temp.step+dis(temp.str)); for(i=0;i<temp.str.length()-1;i++) { string s=temp.str; char c=s[i+1]; s[i+1]=s[i]; s[i]=c; q.step=temp.step+1; q.str=s; if(mp.find(q.str)==mp.end()) { que.push(q); mp[q.str]=true; } } } printf("%d\n",ans); } int main() { while(scanf("%s %s",s1,s2)!=EOF) { mp.clear(); len=strlen(s1); ans=999999999; BFS(); } return 0; }
小疑惑: 为什么只用交换得到状态 然后用2个字符串相加1减1得到的操作数作为结果那
难道不会有可能使得加1减1后 然后进行交换 得到新状态 这时候字符串再相加减得到的距离更短那
求大神指教啊!!!!!
NOJ [1307] English Magic 字符串转化 3种操作 加1 减1 交换相邻字符
最新推荐文章于 2022-06-27 21:17:28 发布