ZOJ 1011

  题目大意:有一颗完全二叉树,给节点一个信号会从一个表中选择一对信号分别传递给两个子节点。最后判断所有叶子节点是否满足给定的规则。题目有点长,具体可参见原题。

  首先是表格中数据的存储,由于会有多个元素,用vector进行保存。其次,树是完全二叉树,可以用数组存储树。然后就是遍历二叉树了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 using namespace std;
 5 
 6 struct Signal
 7 {
 8     int left, right;
 9 };
10 vector<Signal> table[20][20];
11 char tree[2100];
12 
13 int n, m, k;
14 // n is the number of signals, m is the number of accepting signals, k is the number of signal transmitting elements.
15 int l;  // the level of the tree
16 int nodeN;  // the number of nodes of the tree
17 
18 void readTable()
19 {
20     for (int i = 0; i < n; i++)
21         for (int j = 0; j < k; j++)
22         {
23             table[i][j].clear();
24             Signal pair;
25             while (true)
26             {
27                 scanf("%d%d", &pair.left, &pair.right);
28                 table[i][j].push_back(pair);
29                 char ch = getchar();
30                 if (ch == '
')   break;
31             }
32         }
33 }
34 
35 void readTree()
36 {
37     char ch;
38     nodeN = 0;
39     for (int i = 0; i <= l; i++)
40         for (int j = 0; j <  (1<<i); j++)
41         {
42             cin >> ch;
43             tree[++nodeN] = ch;
44         }
45 }
46 
47 bool judge(int signal, int node)
48 {
49     if (tree[node] == '*' || node > nodeN)
50     {
51         if (signal < n-m)   return false;
52         else return true;
53     }
54     int t = tree[node] - 'a';
55     for (int i = 0; i < table[signal][t].size(); i++)
56     {
57         int signal1 = table[signal][t][i].left;
58         int signal2 = table[signal][t][i].right;
59         if (judge(signal1, node*2) && judge(signal2, node*2+1))   return true;
60     }
61     return false;
62 }
63 
64 int main()
65 {
66 #ifdef LOCAL
67     freopen("in", "r", stdin);
68 #endif
69     int kase = 0;
70     while (scanf("%d%d%d", &n, &m, &k) && (n || m || k))
71     {
72         if (kase++)   printf("
");
73         printf("NTA%d:
", kase);
74         readTable();
75         while (scanf("%d", &l) && (l != -1))
76         {
77             readTree();
78             if (judge(0, 1))   printf("Valid
");
79             else   printf("Invalid
");
80         }
81     }
82     return 0;
83 }
View Code

  vector就用过几次,算是熟悉了一下vector的用法吧,clear()清除内容,另外常用的就是puch_back()了,其他的还有pop_back()和insert()。还有那个利用' '判断是否还有数据的方法比用读整行字符串再处理简单多了,然后就是知道了用 cin >> ch 读字符可以跳过空格。最后用递归判断所有叶子节点是否符合要求的思想也让我长见识啦:D。因为输出时把NTA写成NAT,WA了一次,无语...

原文地址:https://www.cnblogs.com/xiaobaibuhei/p/3255468.html