2017阿里巴巴校招在线笔试——货架格子编号

前天晚上顺手做了一下阿里的在线笔试题,还是挺难的,要是现在的水平去校招,估计得跪。

最近有些忙,今天才有时间整理一下之前写的第二题代码。

第二道题目是菜鸟仓库的货架格子编号问题,题目的意思是货架可以按下面的方式进行编号,求从头数下来第k个货物编号是多少?

输出样例:k=5,那么对应第三行第二列,也就是2。k=14,对应第五行第四个,输出4。

我们需要注意的是,从第十行开始,10是分别变成了1和0,11分别是1和1。

也就是说k=55时,输出应该是1,不是10。

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 1 0
1 2 3 4 5 6 7 8 9 1 0 1 1


最简单的思路,把矩阵都打出来,一个个数,当然,这不现实....


其实题目直接可以分成两个子问题,找行:h,和,找列:r。

就像样例中“k=14,对应第h=5行,第r=4个,输出4。”

很多人会觉得10分成了1和0,100分成了1,0和0三个,就不能直接找了。

其实只是略复杂了一点而已。


我们从找列这个问题举例:

如果r很大,前面会有1~9排列的一位数,会有10~99排列的两位数......

那么一位数在货架上占用的位置的总个数就是1*(9-1+1)=1*9,两位数占用总个数是2*(99-10+1)=2*90,三位数占了3*(999-100+1)=3*900

数字规律非常明显。

这样,我们不难算出r对应的是几位数,并且是第几个,也就能得出答案。

我直接贴具体的代码吧:

int find_r(int r){
    int digit=1;  //位数
    int digit_sum=9;   //digit位数下的总个数
    int temp, num, rem, base, loca;

    //num用于锁定数字是digit位数的第几个
    //rem用于后面计算数字中的具体哪一位
    for(;r>digit*digit_sum;digit++,digit_sum*=10){
        r-=digit*digit_sum;
    }
    num=ceil((float)r/digit);
    rem=r%digit;

    //计算小于digit位的最大数
    base=0;
    temp=digit;
    while(temp>1){
        base=base*10+9;
        temp--;
    }

    //loca计算所求位置对应的未分裂的数字
    loca=base+num;
    int ans;
    if(rem!=0)
        rem=digit-rem;
    while(rem>=0){
        ans=loca%10;
        loca=loca/10;
        rem--;
    }
	return ans;
}


输出:
10
1
11
0

14
1
15
2

190
1
191
0
192
0


关于求行数h,其实也是同样的思路,数字都是有规律的,把公式列出来就不难思考,不上代码了。

大家有什么不同的思路交流一下呀~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值