題目:L系統,一個由字符取自{a,b}集合的串,有一個初始串w,目標串z,兩個變換串u、v;
每次得到的新串,將其中的a全部轉化成u,b全部轉化成v,判断能不能生成目标串。
分析:搜索、bfs。
利用w的所有長度不超過z的字串作為初始條件;
每次從隊列中取出新串,將其中所有的a轉化成u,所有的b轉化成v,生成新串;
枚舉新串所有長度不超過目標串的字串,將新出現的存入隊列;
利用2進制作為hash值判重。
說明:poj一直TLE╮(╯▽╰)╭。
#include <cstring>
#include <cstdio>
int hash[(3<<15)+1], head, tail;
char queue[1<<16][16], buf[256], now[16], New[16];
int push(char str[], char z[], int zHashValue)
{
for (int i = 0; str[i]; ++ i) {
int hashValue = 0;
for (int j = i; str[j] && z[j-i]; ++ j) {
New[j-i] = str[j];
hashValue = (hashValue<<1) + str[j]-'a'+1;
if (hashValue == zHashValue) {
return 1;
}
New[j-i+1] = 0;
if (!hash[hashValue]) {
strcpy(queue[tail ++], New);
hash[hashValue] = 1;
}
}
}
return 0;
}
void bfs(char u[], char v[], char w[], char z[])
{
memset(hash, 0, sizeof(hash));
int zHashValue = 0;
for (int i = 0; z[i]; ++ i) {
zHashValue = (zHashValue<<1) + z[i]-'a'+1;
}
head = 0; tail = 0;
if(push(w, z, zHashValue)) {
puts("YES");
return;
}
while (head < tail) {
strcpy(now, queue[head ++]);
int buf_size = 0;
for (int i = 0; now[i]; ++ i) {
if (now[i] == 'a') {//1 -> v
for (int j = 0; u[j]; ++ j) {
buf[buf_size ++] = u[j];
}
}else {//0 -> u
for (int j = 0; v[j]; ++ j) {
buf[buf_size ++] = v[j];
}
}
}
buf[buf_size] = 0;
// insert new node get z return
if (push(buf, z, zHashValue)) {
puts("YES");
return;
}
}
puts("NO");
}
int main()
{
char u[16], v[16], w[16], z[16];
while (gets(u) && gets(v) && gets(w) && gets(z)) {
if (z[0]) {
bfs(u, v, w, z);
}else {
puts("YES");
}
}
return 0;
}