练习二 1021 The magic apple tree

题目:

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<br>2 2 3<br>2 5 4<br>2 6 7<br>0<br>0<br>0<br>0<br><br>12<br>3 2 3 4<br>0<br>2 5 6<br>3 7 8 9<br>3 10 11 12<br>0<br>0<br>0<br>0<br>0<br>0<br>0

Sample Output
  
  
4<br>6

题目大意:在一棵苹果树上,有n个节点,第一天,只有叶节点才有苹果,苹果的数目等于该节点的编号。第二天开始,其他节点开始长苹果,对于非叶节点,只有当所有直接子节点都长了苹果之后才开始长,设它的直接子节点数目为K,则该节点的苹果数等于所有直接字节点苹果数目中的第(K + 1) / 2大。问最后根节点的苹果数目。

分析:一开始没看懂题意,研究了半天都没明白。明白题意之后就好办很多了,用深搜的方法从根节点开始算,往下搜,再递推回来。

感想:用vector数组实现方便好多


代码:

#include<iostream>
#include<algorithm>
#include<vector>
#define MAXN 20000+10
using namespace std;
vector<int> g[MAXN];
int n,v[MAXN],in[MAXN],out[MAXN];
int dfs(int cnt)
{
    if(out[cnt]==0) //叶节点这直接返回编号
        return cnt;
    vector<int> ss;
    for(int i=0;i<out[cnt];i++)
        ss.push_back(dfs(g[cnt][i])); //保存子节点的苹果数,再算出第k+1/2的
    sort(ss.begin(),ss.end());
    return ss[(out[cnt]+1)/2-1];
}
int main()
{
    int a,i;
    while(cin>>n)
    {
		if(n==1) break;
        for(i=1;i<=n;i++)
            g[i].clear();
        memset(in,0,sizeof(in));
        for(i=1;i<=n;i++)
        {
            cin>>out[i];
            for(int j=0;j<out[i];j++)
            {
                cin>>a;
                g[i].push_back(a);
                in[a]++;
            }
        }
        int root;
        for(int i=1;i<=n;i++) //找出根节点
            if(in[i]==0)
            {
                root=i;
                break;
            }
       cout<<dfs(root)<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值