uva 122 小球下落 树的模拟

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=8&problem=620&mosmsg=Submission+received+with+ID+17752885

称号:有一个完整的二叉树,每个节点是一个开关,最初的全封闭,球从顶点丢弃。

            每次通过开关球将将其状态反转。现在先问k球落到d当层交换机经过号。

分析:进制编码。经过模拟几次能够看出,球会让开关形成连续二进制数的表示(根是低位)。

            当放入第k个球时。开关状态正好是二进制的k。利用模2的余数推断走向就可以。

说明:观察规律模拟处理就可以。

超时:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 20;
int s[1<<maxn];
int main()
{
    int n;
    int D,I;
    cin>>n;
    while(n--)
    {
        memset(s,0,sizeof(s));
        cin>>D>>I;
        if(D==-1)
            {
                break;
            }

        int k,n=(1<<D)-1;
        for(int i = 0;i<I;i++)
        {
            k=1;
            while(1)
            {
                s[k]=!s[k];
                k=s[k]?k*2:k*2+1;
                if(k>n) break;
            }
        }
        cout<<k/2<<endl;
    }

return 0;
}

AC:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 20;

int main()
{
    int n;
    int D,I;
    cin>>n;
    while(1){
    
    cin>>D;
    if(D==-1)
    break;
    
    int k=1;
    cin>>I;
    for(int i= 0;i<D-1;i++)
        if(I%2)
    {
        k=k*2;
        I=(I+1)/2;
    }
    else
    {
        k=k*2+1;
        I/=2;
    }
        cout<<k<<endl;
    }


return 0;
}


posted @ 2016-07-29 18:45  Lawliet__zmz  阅读(148)  评论(0编辑  收藏  举报