既DFA,构造一个自动机,根据状态转移,读入一个字符,就跳到另一个节点,若刚好可以形成一个串,对该节点染色。

 

    POJ3332 Parsing Real Numbers

    http://acm.pku.edu.cn/JudgeOnline/problem?id=3332

    构造一个9个节点的自动机就够了,状态为'+' , '-' , '0' ~ '9' , 'e' , 'E',然后若可以合法,则对改点染色。还有一个细节是先把前后两边的空格消掉,可以减少一个状态转移量,少了很多计算。然后在给这个串第一个字符赋值为 '+' 或者 '-',就自己自动机上跳了。

代码
1 #include <cstdio>
2 #include <algorithm>
3  using namespace std;
4
5  const int maxn = 1001;
6
7 char a[maxn], b[maxn];
8 int L, FLAG, go[10][256], color[10];
9
10 void init()
11 {
12 go[1][ '+' ] = 2;
13 go[1][ '-' ] = 2;
14
15 go[4][ '+' ] = 6;
16 go[4][ '-' ] = 6;
17
18 for(int i=0; i <= 9; i++) {
19 go[2][ i + '0' ] = 3;
20 go[3][ i + '0' ] = 3;
21 go[4][ i + '0' ] = 7;
22 go[5][ i + '0' ] = 8;
23 go[6][ i + '0' ] = 7;
24 go[7][ i + '0' ] = 7;
25 go[8][ i + '0' ] = 8;
26 }
27
28 go[3][ 'e' ] = 4;
29 go[3][ 'E' ] = 4;
30
31 go[8][ 'e' ] = 4;
32 go[8][ 'E' ] = 4;
33
34 go[3][ '.' ] = 5;
35
36 color[3] = color[7] = color[8] = 1;
37 }
38
39 void solve()
40 {
41 FLAG = 0;
42 int i, j, k, len = strlen(a);
43
44 for(i=0; a[i] == ' '; i++) ;
45 for(j=len - 1; a[j] == ' '; j--) ;
46
47 if(a[i] == '-') {
48 b[0] = '-';
49 i ++;
50 } else if(a[i] == '+') {
51 b[0] = '+';
52 i ++;
53 } else b[0] = '+';
54
55 L = 1;
56 for(k=i; k <= j; k++)
57 b[L ++] = a[k];
58 b[L] = '\0';
59 }
60
61 void doit()
62 {
63 int root = 1;
64 for(int i=0; i < L; i++) {
65 root = go[root][ b[i] ];
66 if(root == 0) {
67 FLAG = 1;
68 break;
69 }
70 }
71 if(FLAG)
72 puts("ILLEGAL");
73 else {
74 if(!color[ root ])
75 puts("ILLEGAL");
76 else
77 puts("LEGAL");
78 }
79 }
80
81 int main()
82 {
83 int cas;
84 init();
85 scanf("%d", &cas);
86 getchar();
87 while(cas --)
88 {
89 gets(a);
90 solve();
91 doit();
92 }
93 return 0;
94 }

 

posted on 2010-05-22 16:52  xIao.wU 思维磁场  阅读(469)  评论(0编辑  收藏  举报