UVA - 310 L--system(bfs+hash)


 L-system 

A D0L (Deterministic Lindenmayer system without interaction) system consists of a finite set tex2html_wrap_inline36 of symbols (the alphabet), a finite set P of productions and a starting string tex2html_wrap_inline40 . The productions in P are of the form tex2html_wrap_inline44 , where tex2html_wrap_inline46 and tex2html_wrap_inline48 (u is called the right side of the production), tex2html_wrap_inline52 is the set of all strings of symbols from tex2html_wrap_inline36 excluding the empty string. Such productions represent the transformation of the symbol x into the string u. For each symbol tex2html_wrap_inline46 , P contains exactly one production of the form tex2html_wrap_inline44 . Direct derivation from string tex2html_wrap_inline66 to tex2html_wrap_inline68 consists of replacing each occurrence of the symbol tex2html_wrap_inline46in tex2html_wrap_inline66 by the string on the right side of the production for that symbol. The language of the D0L system consists of all strings which can be derived from the starting string tex2html_wrap_inline40 by a sequence of the direct derivations.

Suppose that the alphabet consists of two symbols a and b. So the set of productions includes two productions of the form atex2html_wrap_inline76 , btex2html_wrap_inline78 , where u and tex2html_wrap_inline82 , and the starting string tex2html_wrap_inline84 . Can you answer whether there exists a string in the language of the D0L system of the form xzy for a given string z? (x and y are some strings from tex2html_wrap_inline94 , tex2html_wrap_inline94 is the set of all strings of symbols from tex2html_wrap_inline36 , including the empty string.). Certainly you can. Write the program which will solve this problem.

Input

The input file of the program consists of several blocks of lines. Each block includes four lines. There are no empty lines between any successive two blocks. The first line of a block contains the right side of the production for the symbol a. The second one contains the right side of the production for the symbol band the third one contains the starting string tex2html_wrap_inline40 and the fourth line the given string z. The right sides of the productions, the given string z and the starting string tex2html_wrap_inline40 are at most 15 characters long.

Output

For each block in the input file there is one line in the output file containing YES or NO according to the solution of the given problem.

Sample Input

aa
bb
ab
aaabb
a
b
ab
ba

Sample Output

YES
NO


这题实在是难以理解,并且在写的时候,把一个步骤写成死循环了,一直TLE。

题意:
给出4个字符串
第一个是字符'a'的替换字符串,
第二个是字符'b'的替换字符串,
第三个是初始字符串,
第四个是目标字符串。
问是否初始字符串是否可以经过"L-system"替换形成目标字符串。


替换规则:
(1)将初始的字符串的a和b进行替换,
(2)再将新串中和 目标串长度的子串 提取出来,判断是否相同,如果相同返回"YES"
(3)如果不相同,将子串中的a和b进行替换,并跳到步骤(2)

解析:这题用到bfs+hash,bfs用于枚举出所有的子串,而hash用于判断是否重复。

#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <queue>
#include <iostream>
using namespace std;
const int MAX = 1 << 16;
string a,b,begin,end;
queue<string> q;
bool vis[MAX];
int hash(string str) {
	int v = 0;
	for(int i = 0; i < str.size(); i++) {
		v = v*2 + str[i] - 'a' + 1;
	}
	return v;
}
void init() {
	memset(vis,0,sizeof(vis));
	while(!q.empty()) {
		q.pop();
	}
}
bool bfs() {
	init();
	string tmp;
	int v,over = hash(end);
	for(int i = 0; i < begin.size(); i++) {
		tmp = "";
		for(int j = i,k = 0; j < begin.size() && k < end.size(); j++,k++) {
			tmp += begin[j];
		}
		v = hash(tmp);
		if(v == over) {
			return true;
		}else if(!vis[v]) {
			vis[v] = true;
			q.push(tmp);
		}
	}
	while(!q.empty()) {
		string front = q.front();
		q.pop();
		tmp = "";
		for(int i = 0; i < front.size(); i++) {
			if(front[i] == 'a') {
				tmp += a;
			}else {
				tmp += b;
			}
		}
		for(int i = 0; i < tmp.size(); i++) {
			string tmp2 = "";
			for(int j = i,k = 0; j < tmp.size() && k < end.size(); j++,k++) {
				tmp2 += tmp[j];
			}
			v = hash(tmp2);
			if(v == over) {
				return true;
			}else if(!vis[v]) {
				vis[v] = true;
				q.push(tmp2);
			}
		}
	}
	return false;
}
int main() {
	bool ok;
	while(cin >> a) {
		cin >> b >> begin >> end;
		ok = bfs();
		if(ok) {
			cout << "YES" << endl;
		}else {
			cout << "NO" <<endl;
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值