ACM训练合集---HDU4545 魔法串

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)


解题思路
本题实际上是要找 母串中的字符在相对位置不变的情况下,是否可以经过组合(删除或转变)形成目标子串。
什么叫相对位置?比如母串为adcd要始终在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,如果小伙伴有更好的思路可以在评论区分享。

学无止境,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值