Placing Medals on a Binary Tree Gym - 101158G (The 2016 Asia Regional Contest, Tsukuba)

题意: 现在有一颗满二叉树,现在有n个金牌,每个金牌上刻着一个数字x,代表这个金牌要放在深度为x的节点上,放金牌有一个规则就是这个节点到根节点的路上不能经过其他节点,从前向后放金牌,能放就放下输出Yes,放不下就跳过放下一个输出No.

做法:首先我们可以将这个满二叉树想象成二进制,每次加一个节点,就是加1/y,y=2^x,也就相当于在二进制的这一位上加了一个1,当什么时候这棵树加满了就不行了,或者允许加的值比我的值小,也就是我这一位的前年没有0的存在了,那么也是不可以的。

为什么场上没有写呢:首先是想到了二进制的,但是觉得每次更新需要向前更新很远,可能会超时,就没有写。

为什么现在写了呢:稍微优化了一点就是,我们判断某一个点是否可行的时候,不是从1号直接判断到x号找零了,西施我保存了一个最前面的零的位置,也就是这个值前面全部都是1,这样的话,我每次只需要从后面的一段寻找就可以了,还有一个就是,层数低于这个值的,我们已经知道前面全都是1了,可以直接跳出。 当已经放满1了的时候所有值都放不进去了,也是跳出,例如放了一个第一层的,两个第二层的,那么之后无论放什么都放不进去,因为已经满了。

代码如下:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>

using namespace std;

map<int,int>mp;   ///记录每一层现在的值是多少 1代表不能再放了 0代表还可以放
int n;
int num;   ///输入的值 奖牌上的数值
int maxx;   ///记录了现在哪一层被放满了 这样的话 在它上面就不能放了  在它下面还可以放 于是需要保存最大值

int main()
{
        scanf("%d" , &n);
        mp[0] = 0;   ///初始值一个都还没有放
        maxx = 0;    ///题目给出金牌不可以放在根节点上
        while( n-- )
        {
            scanf("%d" , &num);
            if(num<=maxx || mp[0]==1)
            {
                ///如果这个金牌要放在满层的上面 是放不下的  或者现在整棵树都放满了 也是放不下的了
                printf("No\n");
                continue;
            }
            bool flag = false;  ///判断这个值能否放下 如果在它之前包括它自己含有可以放的层 那么它就可以放下
            for(int i=maxx+1; i<=num; i++)
            {
                if(mp[i]==0)
                {
                    flag = true;
                    break;
                }
                maxx++;   ///前面连续的都是0  就可以更新maxx
            }
            if(!flag)
            {
                printf("No\n");
                continue;    ///如果在它之前放不下 那么此时就放不下了
            }
            int i = num;
            mp[i]++;
            while(i>=0)
            {
                if(mp[i]==2)
                {
                    mp[i]=0;
                    mp[i-1]+=1;
                    i--;
                }
                else
                {
                    break;
                }
            }
            printf("Yes\n");
//            for(int i=0; i<=5; i++)
//            {
//                printf("%d " , mp[i]);
//            }
//            printf("\n%d...\n" , maxx);
    }




    return 0;
}

 

posted @ 2018-10-14 20:13  Flower_Z  阅读(231)  评论(0编辑  收藏  举报