zyb的面试(广工14届)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6468

上次ZOJ上也遇到这道题不会写,更重要的是还没补!!!这次又遇到,可以说是对我的惩罚……

所以这次铁了心也要学会这道题。

我问广工某大佬拿了份题解加了点自己的注释 Orz%%%

弱鸡看完表示一脸懵逼,但还是坚持看下来了!!!

这个是之后要用到的树,在此之前先明确,每颗这样的树的满多叉树有多少个节点。然后就是这颗树每层的节点数。

#include <bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
void read(int &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch-'0';
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=a*10+ch-'0';
    a*=d;
}
void write(int x)
{
    if(x<0)
        putchar(45),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
const int L=10;
int f[L],a[L],ten[L],cnt;///f存满十叉树的一共节点数,ten存当前层数的节点数
void geta(int n)
{
    cnt=0;
    while(n)
    {
        a[cnt++]=n%10;
        n/=10;
    }
}
int main()
{
    f[0]=ten[0]=1;
    for(re int i=1;i<L;i++)///初始化
    {
        f[i]=f[i-1]*10+1;
        ten[i]=ten[i-1]*10;
    }
    int T;
    read(T);
    while(T--)
    {
        int n,k;
        read(n);
        read(k);
        geta(n);
        int ans=0,cmp=0;
        for(re int i=cnt-1;i>=0&&k;i--)///枚举层数
            for(re int d=(ans==0);d<10;d++)///ans==0作用:因为第一位数不可能为0,所以第一个循环从1开始,之后的位数从0开始。
            {
                int siz=0;
                if(0==cmp)
                {
                    if(d<a[i])///若当前位置比a[i]小,说明d这颗树是有i层的满多叉树
                        siz=f[i];
                    else if(d==a[i])///相等则可能在中间某一段就停止的,就像样例中n==15,在1节点的完全多叉树中,但到15就结束了。
                        siz=f[i-1]+n-(ans*10+d)*ten[i]+1;///计算这颗树有多少个点
                    else
                        siz=f[i-1];
                }
                else if(cmp==-1)
                    siz=f[i];
                else
                    siz=f[i-1];
                if(k>siz)///如果k比这颗树的节点大,很明显他就在下一颗树上。
                    k-=siz;
                else///在这一颗树上找k的位置是哪个数。
                {
                    k--;
                    ans=ans*10+d;///很明显,在这颗树上的话,这颗树的第一个点肯定是d
                    if(0==cmp)
                        cmp=(d>a[i])-(d<a[i]);
                    break;
                }
            }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/acm1ruoji/p/10548991.html