The magic apple tree
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 26 Accepted Submission(s) : 2
Problem Description
Sailormoon girls all like eating many kinds of fruit, such as banana, grape, apple and so on.<br>One day, when they was walking on a orchard, they found a magic apple tree.The magic apple tree have many nodes,but there is only one root. Each notes has its label. It is labeled from 1.On the first day,only each leaf nodes(has no children nodes) have apples. Any other nodes have no apples. The number of apples that each leaf nodes have is just the label of this node.When all the immediate children of a node each has apples,this node will grow some apple on the next day. If a node has K immediate children node,the number of apple that this node grow on next day is just the number of apples that the (K + 1) / 2th smaller node has.The Xth smaller node means there are X – 1 nodes’ number of apples is less than this node’s number of apple.<br>Now you task is to calculate the number of apples that the root has at last.
Input
There are multiple test cases.<br>Each case
contains a positive integer N, it means this tree has N nodes, labeled 1, 2, ...
N(0 < N <= 20000).<br>The following N lines describe the children of
all nodes in order of their labels. The (X + 1)th line in each test case starts
with a number p (0 <= p <N), it means the Xth node has p immediate
children nodes.then followed by p positive integer, means the label of immediate
child node
Output
Print the number of apples that the root grow at
last.
Sample Input
7
2 2 3
2 5 4
2 6 7
0
0
0
0
12
3 2 3 4
0
2 5 6
3 7 8 9
3 10 11 12
0
0
0
0
0
0
0
Sample Output
4
6
简单题意:
树上有N个节点,每个节点又有子节点,第一天叶节点结果子,数目等于编号,第二天,其他非叶节点才开始结果子, 对于非叶节点,假设有K个子节点,那么他接的果子为子节点第(K + 1) / 2大的数,求根节点。。
思路分析:
一开始题目都很难理解,后来就是一直超时,,,,用了输入外挂后就可以了。。。dfs搜索。。
# include <iostream> # include <fstream> # include <cstring> # include <cstdio> # include <algorithm> # include <vector> using namespace std; vector <int> map[20001]; int is[20001], father[20001]; int dfs(int); char c;//网上查的输入外挂 inline void f(int & x) { while(c = getchar(), c < ‘0‘ || c > ‘9‘); x = c - ‘0‘; while(c = getchar(), c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘; } int main() { //freopen("aaa.txt", "r", stdin); int n, t; while(scanf("%d", &n) == 1) { memset(is, 0, sizeof(is)); for(int i = 1; i <= n; i++) map[i].clear(); for(int i = 1; i <= n; i++) { f(father[i]); // 直接子节点的父节点 for(int j = 0; j < father[i]; j++) { f(t); map[i].push_back(t); is[t] = 1; // 判断根节点, } } int root; for(int i = 1; i <= n; i++ ) if(is[i] == 0) root = i; printf("%d\n", dfs(root)); } return 0; } int dfs(int root) { vector <int> tep; if(father[root] == 0) // 当子节点为0时, 直接返回号码 return root; for(int i = 0; i < father[root]; i++) tep.push_back(dfs(map[root][i])); sort(tep.begin(), tep.end()); return tep[(father[root] + 1) / 2 - 1]; }