HNU_11704
这个和POJ的3332十分类似,都是判断一个字符串是否合法,具体怎么想可以参考一下我的另一篇题解,http://www.cnblogs.com/staginner/archive/2012/01/24/2329131.html,代码为了看起来思路清晰一些,所以写得就十分啰嗦了,很多地方是可以简化的。
由于单词很多,如果暴搜判断有无的话时间消耗比较大,不过这个题直接暴搜单词也是过得了的,比较快的方式就是用二分、哈希表、字典树。
此外这个题目好像给出的noun和verb的长度有的是超过6的,不过如果使用字典树记录的话基本是没有问题的,但用哈希表的话就要注意这个长度的问题了。
#include<stdio.h>
#include<string.h>
#define MAXL 500010
#define MAXD 60010
int N, M, pat;
char b[MAXL];
int ntree[MAXD][26], noun[MAXD], ne, vtree[MAXD][26], verb[MAXD], ve;
void insert_noun(int cur, int k)
{
++ ne;
noun[ne] = 0;
memset(ntree[ne], 0, sizeof(ntree[ne]));
ntree[cur][k] = ne;
}
void insert_verb(int cur, int k)
{
++ ve;
verb[ve] = 0;
memset(vtree[ve], 0, sizeof(vtree[ve]));
vtree[cur][k] = ve;
}
void init()
{
int i, j, k, cur;
ne = ve = 0;
noun[ne] = verb[ve] = 0;
memset(ntree[ne], 0, sizeof(ntree[ne]));
memset(vtree[ve], 0, sizeof(vtree[ve]));
for(i = 0; i < N; i ++)
{
gets(b);
cur = 0;
for(j = 0; b[j]; j ++)
{
k = b[j] - 'a';
if(!ntree[cur][k])
insert_noun(cur, k);
cur = ntree[cur][k];
}
noun[cur] = 1;
}
for(i = 0; i < M; i ++)
{
gets(b);
cur = 0;
for(j = 0; b[j]; j ++)
{
k = b[j] - 'a';
if(!vtree[cur][k])
insert_verb(cur, k);
cur = vtree[cur][k];
}
verb[cur] = 1;
}
}
void delblank(int &i)
{
while(b[i] == ' ')
++ i;
}
void delword(int &i)
{
while(b[i] && b[i] != ' ')
++ i;
}
int find_and(int i)
{
if(b[i] == 'a' && b[i + 1] == 'n' && b[i + 2] == 'd' && b[i + 3] == ' ')
return 1;
return 0;
}
int find_comma(int i)
{
if(b[i] == ',')
return 1;
return 0;
}
void pattern(int i)
{
if(pat == 0)
{
pat = 1;
}
else if(pat == 1)
{
pat = 2;
}
else if(pat == 2)
{
if(find_and(i))
pat = 3;
else
pat = 4;
}
else if(pat == 3)
{
pat = 2;
}
else if(pat == 4)
{
pat = 5;
}
else if(pat == 5)
{
if(find_and(i))
pat = 6;
else if(find_comma(i))
pat = 7;
else
pat = 8;
}
else if(pat == 6)
{
pat = 5;
}
else if(pat == 7)
{
pat = 2;
}
else if(pat == 8)
{
pat = 9;
}
}
int find_noun(int i)
{
int k, cur;
cur = 0;
for(; b[i] && b[i] != ' '; ++ i)
{
k = b[i] - 'a';
if(!ntree[cur][k])
return 0;
cur = ntree[cur][k];
}
return noun[cur];
}
int find_verb(int i)
{
int k, cur;
cur = 0;
for(; b[i] && b[i] != ' '; ++ i)
{
k = b[i] - 'a';
if(!vtree[cur][k])
return 0;
cur = vtree[cur][k];
}
return verb[cur];
}
int find_fix(int i)
{
if(b[i] != '[')
return 0;
for(; b[i] && b[i] != ' '; ++ i);
if(b[i - 1] != ']')
return 0;
return 1;
}
int check(int i)
{
if(pat == 1)
{
if(find_fix(i))
return 1;
else
return 0;
}
else if(pat == 2)
{
if(find_noun(i))
return 1;
else
return 0;
}
else if(pat == 3)
{
if(find_and(i))
return 1;
else
return 0;
}
else if(pat == 4)
{
if(find_verb(i))
return 1;
else
return 0;
}
else if(pat == 5)
{
if(find_noun(i))
return 1;
else
return 0;
}
else if(pat == 6)
{
if(find_and(i))
return 1;
else
return 0;
}
else if(pat == 7)
{
if(find_comma(i))
return 1;
else
return 0;
}
else if(pat == 8)
{
if(find_fix(i))
return 1;
else
return 0;
}
return 0;
}
int solve()
{
int i, j, k;
gets(b);
pat = 0;
for(i = 0, delblank(i); b[i];)
{
pattern(i);
if(!check(i))
return 0;
delword(i);
delblank(i);
}
if(pat == 8)
return 1;
else
return 0;
}
int main()
{
while(gets(b) != NULL)
{
sscanf(b, "%d%d", &N, &M);
init();
if(solve())
printf("a good title\n");
else
printf("a bad title\n");
}
return 0;
}