HNU 11704 Baidu Post Bar
来源:互联网 发布:js键值对集合 编辑:程序博客网 时间:2024/04/30 02:39
http://acm.hnu.cn/online/?action=problem&type=show&id=11704&courseid=0
题意:给你一堆语法规则,再给你一个表达式,问你这个表达式是否合法。
思路:DFA,构造一个有限状态自动机,然后进行状态转移。
代码:
#include<stdio.h>#include<string.h>#include<ctype.h>const int MAXN = 10010 ;int N, M ;struct Node{int f ;struct Node *next[26] ;}p1[500010] ,*root1 ,p2[500010] ,*root2 ;int cnt1,cnt2; char pp[211000] ;char name[20] ;void Build1(char *ch){int i, j ,idx; i = 0 ;Node *loc = root1 ,*q ;for( ; ch[i] != 0; i++){idx = ch[i] - 'a' ;if(loc->next[idx] == NULL){q = &p1[cnt1] ;q->f = 0; memset(q->next , 0 ,sizeof(q->next));loc->next[idx] = q ;cnt1 ++ ;} loc = loc->next[idx] ;}loc->f = 1 ;}void Build2(char *ch){int i, j ,idx; i = 0 ;Node *loc = root2 ,*q ;for( ; ch[i] ; i++){idx = ch[i] - 'a' ;if(loc->next[idx] == NULL){q = &p2[cnt2] ;q->f = 0; memset(q->next , 0 ,sizeof(q->next));loc->next[idx] = q ;cnt2 ++ ;}loc = loc->next[idx] ;}loc->f = 1 ;}int f[10][10] ;void Init(){memset(f , -1 ,sizeof(f));f[1][1] = 2 ;f[2][2] = f[8][2] = 3 ;f[3][4] = 8 ;f[3][3] = 4 ;f[4][2] = f[6][2] = 5 ;f[5][4] = 6 ;f[5][6] = 7 ;f[5][5] = 2 ;}bool is_noun(char *ch){Node *loc = root1 ;int idx ;for(int i=0;ch[i]!=0;i++){idx = ch[i] - 'a' ;if( loc->next[idx] == NULL)return false ;loc = loc->next[idx] ;}return loc->f ; }bool is_verb(char *ch){Node *loc = root2 ;int idx ;for(int i=0;ch[i]!=0;i++){idx = ch[i] - 'a' ;if( loc->next[idx] == NULL)return false ;loc = loc->next[idx] ;}return loc->f ;}bool is_and(char *ch){return strcmp(ch , "and") == 0;}bool is_one(char *ch){return strcmp(ch , ",") == 0 ;}int judge(char *ch){int i , j ;if( is_noun(ch) )return 0 ;if( is_verb(ch) )return 1 ;if( is_and(ch) )return 2 ;if( is_one(ch) )return 3 ;return -1 ;}/*prefix : 1 noun : 2 verb : 3and : 4, : 5 sufix : 6 */bool DFA(){int state = 1 ;int len = strlen(pp);int i= 0 ,j;while(i<len && (pp[i]==' '||pp[i]=='\t') ) i++ ;if( pp[i]!='[')return false ;bool blank = 0 ;for( ;i<len && pp[i]!=']';i++){if(pp[i]==' ' || pp[i]=='\t'){blank = 1 ; break ;}}if(blank)return false ;i++ ;j = len - 1 ;while(j>=i && (pp[j]==' '||pp[j]=='\t'))j-- ;if(pp[j] != ']')return false ;blank = 0 ;for( ;j>=i && pp[j]!='[';j--){if(pp[j]==' ' || pp[j]=='\t'){blank = 1 ; break ;}}if(blank)return false ;j-- ; while(j>=i && (pp[j]==' '||pp[j]=='\t'))j-- ;len = j + 1;state = f[state][1] ;while(i<len){while(i<len && (pp[i]==' '||pp[i]=='\t'))i++ ;for(j=0 ;i<len ;i++ , j++){if( pp[i]!=' ' && pp[i]!='\t' ){name[j] = pp[i] ;}elsebreak ;}name[j] = 0 ;int kind = judge(name);switch(kind){case 0 :state = f[state][2] ; break ;case 1 :state = f[state][3] ; break ;case 2 :state = f[state][4] ; break ;case 3 :state = f[state][5] ; break ;default :return false ;}if(state == -1)return false ;}return true ;}int main(){while(scanf("%d %d",&N,&M) == 2){root1 = &p1[0] ;root1->f = 0 ; cnt1 = 1 ;memset(root1->next, 0 ,sizeof(root1->next));for(int i=0;i<N;i++){scanf("%s",name);Build1(name); }root2 = p2 ;root2->f = 0 ; cnt2 = 1 ;memset(root2->next, 0 ,sizeof(root2->next));for(int i=0;i<M;i++){scanf("%s",name);Build2(name); }getchar() ;gets(pp);Init(); if(DFA())printf("a good title\n");else printf("a bad title\n");}return 0 ;}
- HNU 11704 Baidu Post Bar
- baidu
- Baidu?
- baidu
- baidu
- baidu
- baidu
- http://post.baidu.com/f?kz=261991447
- bar
- bar
- HNU 11877
- hnu 病毒
- hnu 12948
- HNU Profits
- HNU 21
- acm hnu 10136 Palindromes
- hnu 12029 LCA问题
- hnu 12439 #贪心
- 算法库(一)
- C++多线程入门(二)
- Telerik的Test Studio R1 2012 新功能
- 最近干了什么
- 基于嵌入式Linux的视频采集系统16-----源程序----v4l_driver.h
- HNU 11704 Baidu Post Bar
- 百度2011年9月面试题
- mysql 日期详细操作
- 基于嵌入式Linux的视频采集系统17-----源程序----decoder.h
- problem 11 矩阵中连续四个数的最大积
- 2011湖南省ACM大赛G题
- VC++ INI文件修改,读取键值
- 赵雅智_java 接口
- eclipse快捷键