Problem Description
小明和他的好朋友小西在玩一个新的游戏,由小西给出一个由小写字母构成的字符串,小明给出另一个比小西更长的字符串,也由小写字母组成,如果能通过魔法转换使小明的串和小西的变成同一个,那么他们两个人都会很开心。这里魔法指的是小明的串可以任意删掉某个字符,或者把某些字符对照字符变化表变化。如:
小西的串是 abba;
小明的串是 addba;
字符变化表 d b (表示d能转换成b)。
那么小明可以通过删掉第一个d,然后将第二个d转换成b将串变成abba。
现在请你帮忙判断:他们能不能通过魔法转换使两个人的串变成一样呢?
Input
首先输入T,表示总共有T组测试数据(T <= 40)。
接下来共T组数据,每组数据第一行输入小西的字符串,第二行输入小明的字符串(数据保证字符串长度不超过1000,小明的串的长度大于等于小西的,且所有字符均为小写字母)。接着输入字母表,先输入m,表示有m个字符变换方式(m< = 100),接着m行每行输入两个小写字母,表示前一个可以变为后一个(但并不代表后一个能变成前一个)。
Output
对于每组数据,先输出Case数。
如果可以通过魔法转换使两个人的串变成一样,输出“happy”,
否则输出“unhappy”。
每组数据占一行,具体输出格式参见样例。
Sample Input
2
abba
addba
1
d b
a
dd
0
Sample Output
Case #1: happy
Case #2: unhappy
Source
2013金山西山居创意游戏程序挑战赛——初赛(1)
解题思路
本题实际上是要找 母串中的字符在相对位置不变的情况下,是否可以经过组合(删除或转变)形成目标子串。
什么叫相对位置?比如母串为adc
,d
要始终在a
的后面,c
始终要在最后一个位置,这就叫相对位置。
因为字符串不长,所以时我们可以使用暴力匹配方式来解决。大致解题流程如下:
实现代码:
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
bool magicstr(char s1[], char s2[], multimap<char, char> r){
int i,j;
// index:记录小明字符串的下标
// num:记录两个字符串匹配成功的字符数
int index = 0, num = 0;
int len1 = strlen(s1);
int len2 = strlen(s2);
for (i = 0; i < len1; i++){
// 标记位,判断通过规则转换是否可以匹配成功
bool flag = false;
for (j = index; j < len2; j++){
if (s1[i] == s2[j]){
index = j+1; num++;
break;
}
else{
if (r.size() != 0){
multimap<char, char>::iterator it;
for (it = r.begin(); it != r.end(); it++){
if (it->first == s2[j] && it->second == s1[i]){
index = j+1; num++;
flag = true;
break; //跳出规则转换的for循环
}
}
}
if (flag) break; //跳出遍历小明字符串的for循环
}
}
}
// 匹配成功的字符串跟小西字符串长度一样的话就true
if (num == len1) return true;
return false;
}
int main(){
char s1[1001], s2[1001]; //接收输入的字符串
int t;
int i, j, m;
char c1, c2; // 接收规则中的那两个字符
cin >> t;
for (i = 0; i < t; i++){
// 存放规则的map
multimap<char, char> rule;
scanf("%s%s", s1, s2);
cin >> m;
for (j = 0; j < m; j++){
cin >> c1 >> c2;
// 将每个规则放在map中
rule.insert(pair<char, char>(c1, c2));
}
if (magicstr(s1, s2, rule)){
cout << "Case #"<< i+1 <<": happy" << endl;
}
else{
cout << "Case #" << i+1 << ": unhappy" << endl;
}
}
return 0;
}
程序详情流程图如下:
这是个人的做题的一些想法及代码实现。已AC,如果小伙伴有更好的思路可以在评论区分享。
学无止境,加油!