字串变换 (2002 年NOIP全国联赛提高组)
一道看似非常水的题
大意 :将一个字串 经过几种变换规则变为给定的另一个子串 ,求最小操作数。
已知有两个字串 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。
思路:从前从后双向BFS 不加限制 若递归次数等于10次仍未找到答案时,输出NO ANSWER 。其他的若替换完后 从 前端BFS的串 在从后端BFS出现过,则此时递归次数乘2减一即为答案, 从后端BFS的情况同上。 具体实现,就按照题意来,依次扫描变换规则,进行替换,替换完的字串加入队列。
双向BFS
#include <iostream>
#include <cstring>
#include <map>
#include <cstdio>
using namespace std;
const int Max = ;
string A, B;
string s_change [][], Front[Max], Back[Max];
int Limit = , head_Front = , tail_Front = , tail_Back = , head_Back = , tot = ;
map < string , int > Map_Front;
map < string , int > Map_Back;
void BFS ()
{
tot++; //记录递归次数
string s, s_replace; // s是 变换后的字串 ,s_replace 是当前需变换的字串
int head, tail;
head = head_Front; //调整指针
tail = tail_Front;
for (int i = head; i <= tail; i++)
for (int j = ; j <= Limit; j++) //变换种数 ,变为不同的替换规则
{
int change_Front = ;
while (change_Front != -) //每个字串中可以替换的字串不止一个
{
s_replace = Front [i]; //取出当前需被变换的字串
change_Front = s_replace.find (s_change [j][], change_Front ); //查找变换规则 ,change_Front是 当前规则 出现的位置
if (change_Front >= )
{
s = s_replace.replace (change_Front, s_change [j][].length(), s_change [j][]); //进行替换, s存的是替换完的字串
if (Map_Front [s] == ) //剪枝 ,若该字串出现过,则不进入队列
{
if (Map_Back [s] != ) //如果能在中间遇到,就直接输出答案
{
cout << tot * - ;
return ;
}
Front [++tail_Front] = s; //加入队列
Map_Front [s] = ; //标记为出现过
}
}
if (change_Front != -) change_Front += s_change[j][].length(); //寻找下一个字串
}
}
head_Front = tail + ; //同上 ,不过是从后面进行BFS
head = head_Back;
tail = tail_Back;
for (int i = head; i <= tail; ++i)
for (int j = ; j <= Limit; ++j)
{
int change_Back = ;
while (change_Back != -)
{
s_replace = Back[i];
change_Back = s_replace.find (s_change[j][], change_Back);
if (change_Back >= )
{
s = s_replace.replace (change_Back, s_change [j][].length(), s_change[j][]);
if (Map_Back[s] == )
{
if(Map_Front[s] != )
{
cout << tot * ;
return ;
}
Back[++tail_Back] = s;
Map_Back[s] = ;
}
}
if (change_Back != -) change_Back = change_Back + s_change [j][].length();
}
}
head_Back = tail + ;
if (tot == ) //以十次为限,若十次后仍未找到,则输出NO ANSWER
{
cout << "NO ANSWER!";
return;
}
BFS ();
}
int main()
{
ios::sync_with_stdio (false);
cin >> A >> B;
while (cin >> s_change[Limit][] >> s_change [Limit][]) Limit++;
Limit--; // 替换的组数
Map_Front [A] = ; //用 map 记录
Map_Back [B] = ;
Front [] = A; //加入队列
Back [] = B;
BFS ();
return ;
}
注意:此题属于那种看似很水,但是实现有难度的题。。
字串变换 (2002 年NOIP全国联赛提高组)的更多相关文章
- 1099 字串变换 2002年NOIP全国联赛提高组
1099 字串变换 2002年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 已知有 ...
- codevs 1098 均分纸牌 2002年NOIP全国联赛提高组 x
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,但纸牌总数必 ...
- 1009 产生数 2002年NOIP全国联赛普及组
1009 产生数 2002年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给出一个整数 n(n< ...
- Codevs 1010 过河卒 2002年NOIP全国联赛普及组
1010 过河卒 2002年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description 如图,A 点有一个过河卒 ...
- 1008 选数 2002年NOIP全国联赛普及组
1008 选数 2002年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description ...
- 1010 过河卒 2002年NOIP全国联赛普及组codevs
1010 过河卒 2002年NOIP全国联赛普及组codevs 题目描述 Description 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点 ...
- Codevs 1171 潜伏者 2009年NOIP全国联赛提高组
1171 潜伏者 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description [问题描述] R 国和S 国正陷 ...
- 1154 能量项链 2006年NOIP全国联赛提高组 codevs
1154 能量项链 2006年NOIP全国联赛提高组 codevs 题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头 ...
- 过河 2005年NOIP全国联赛提高组(离散化+dp)
1105 过河 2005年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在河上有一 ...
随机推荐
- [转]iOS Anti-Debugging Protections
source-1: http://www.coredump.gr/articles/ios-anti-debugging-protections-part-1/ source-2: http://ww ...
- 企业架构研究总结(41)——企业架构与建模之ArchiMate的由来和详述(上)
终于完成了关于企业架构框架理论的总结,谢谢各位看官的支持,能挺过之前过于理论化的叙述而坚持到现在着实不易,笔者也自愧没有实践经验可以分享,希望日后有兴趣的看官能够不吝赐教.在本系列后面的也是最后一个大 ...
- 记一次有趣的互联网事件及console.log~
寂寞的中国互联网又一次瘫痪了. 说是顶级域的根挂了,不知道是黑客还是某个实习生干挂的. 反正到现在还没有人来解释这件事. 先普及一下,为什么顶级域的根挂了全中国都挂了. 那是因为dns解析的特点是递归 ...
- js chart
如何在我们项目中利用开源的图表(js chart) 最近觉得应该把自己在技术上的一些心得记录在博客里面跟大家分享,一起讨论,一起成长! 这篇随笔主要为介绍chart在项目中的运用,因为在我们看到一 ...
- JS获取table表格任意单元格值
jsp页面表格布局 <body onload="show()"> <center> <input type="text" valu ...
- 启动mysql错误解决方案,学会查看错误日志:mysql.sock丢失,mysqld_safe启动报错
本人还是个菜鸟,下面是我的经验之谈,能解决一些问题,有不对的地方,敬请斧正. 我的是CentOS6.3+MySQL5.1.57. 重启了一次服务器后,使用> mysql -u root -p登陆 ...
- Ajax实现天气预报功能
实现天气预报功能 闲来无聊,写下此文 经常看见很多网站上有那种天气预报功能,自己之前也写过一个,不过属于那种涉及WCF服务引用那种,今天发现一个更为简单的方式来实现,使用Javascript和Ajax ...
- MVC3+EF5.0 code first+Flexigrid+ajax请求+jquery dialog 增删改查
MVC3+EF5.0 code first+Flexigrid+ajax请求+jquery dialog 增删改查 本文的目的: 1.MVC3项目简单配置EF code first生成并初始化数据 ...
- Arduino 串口篇 Arduino发送二进制 send binary via RS232-to-USB to PC
有用的链接在这里:http://hi.baidu.com/mizuda/item/06b7fdc1d0e45a0ec710b2dd 更加详细的内容请查阅Arduino官方:http://arduino ...
- fastboot,bootloader,recovery
Fastboot模式,在这个模式下,我们可以为手机进行解锁.可以在该模式下连接电脑进行软件或者指令解锁(s-off),这个模式也称“下载模式” Fastboot fastboot是一种比recover ...