UVa 310 & ZOJ 1306 - L--system

来源:互联网 发布:总决赛数据谁比乔丹强 编辑:程序博客网 时间:2024/05/20 16:31

传送门UVa 310 & ZOJ 1306 - L--system


题意不好理解,我是参考了miss_minor的解题报告才看懂的。


题意是给出一个字符串a,一个字符串b,一个字符串start, 一个字符串target。从左到右,如果遇到a就替换成字符串a,遇到b就替换成字符串b,问能不能替换出包含target的字符串。


一开始使用string+map做的,不知怎么一开始就Memory Limit Exceed了。。


后来看到miss_minor的解法。

把每个待处理的字符串分解成n个子串,子串的长度小于target,再对子串进行替换,用哈希判重。


参(chao)考(xi)了miss_minor的代码。

不过POJ上死活过不了,应该还有更好的算法。。以后再研究。。。


#include <cstdio>#include <cstring>using namespace std;const int HashSize = (1 << 16);char start[30], target[30];char a[30], b[30], temp[500];char qu[HashSize][20];int stopValue, vis[HashSize];bool BFS();int Hash(char *c);void Init();int main(){//freopen("input.txt", "r", stdin);while (~scanf("%s", a)){scanf("%s%s%s", b, start, target);memset(qu, 0, sizeof(qu));stopValue = Hash(target);bool flag = BFS();if (flag)printf("YES\n");elseprintf("NO\n");}return 0;}bool BFS(){memset(vis, 0, sizeof(vis));memset(temp, 0, sizeof(temp));int front = 0, rear = 0;int i, j, k;for (i = 0; start[i]; i++)//一开始先获得start的子串,存在队列里{for (j = i, k = 0; start[j] && target[k]; j++) //子串满足两个条件:1. 不超过start. 2.长度不超过targetqu[rear][k++] = start[j];qu[rear][k] = 0;int value = Hash(qu[rear]);//计算哈希值if (value == stopValue)return true;if (!vis[value]){vis[value] = 1;rear++;}}while (front < rear){for (i = 0, k = 0; qu[front][i]; i++)//生成新的字符串{if (qu[front][i] == 'a')strcat(temp, a);else if (qu[front][i] == 'b')strcat(temp, b);}for (i = 0; temp[i]; i++)//把新的字符串的子串加入队列{for (j = i, k = 0; temp[j] && target[k]; j++)qu[rear][k++] = temp[j];qu[rear][k] = 0;int value = Hash(qu[rear]);if (value == stopValue)return true;if (!vis[value]){vis[value] = 1;rear++;}}memset(temp, 0, sizeof(temp));front++;}return false;}int Hash(char *c){int hashValue = 0;for (int i = 0; i < strlen(c); i++)hashValue = hashValue * 2 + c[i] - 'a' + 1;return hashValue % HashSize;}


0 0
原创粉丝点击