题目大意:有一颗完全二叉树,给节点一个信号会从一个表中选择一对信号分别传递给两个子节点。最后判断所有叶子节点是否满足给定的规则。题目有点长,具体可参见原题。
首先是表格中数据的存储,由于会有多个元素,用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 }
vector就用过几次,算是熟悉了一下vector的用法吧,clear()清除内容,另外常用的就是puch_back()了,其他的还有pop_back()和insert()。还有那个利用' '判断是否还有数据的方法比用读整行字符串再处理简单多了,然后就是知道了用 cin >> ch 读字符可以跳过空格。最后用递归判断所有叶子节点是否符合要求的思想也让我长见识啦:D。因为输出时把NTA写成NAT,WA了一次,无语...