阿里巴巴校招算法(黑板50个数字问题)

本文解析了2013年阿里巴巴校园招聘中的一道算法题,探讨了如何通过一系列特定操作后,黑板上剩余的数字可能性及其背后的数学原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  2013年9月22日 阿里巴巴校招 算法、研发 题之(仅供学习讨论)
 在黑板上写下50个数字:1至50,在接下来的49轮操作中,每次做如下操作,选取两个黑板上的数字a和b

 擦去,在黑板上写|b-a|,请问最后一次动作之后剩下数字可能是什么?为什么?(不用写代码,不写原因不得分)。


 
 分析 : 1、总和为 s=50×51/2=1275 假设 操作若干次 后剩余一个数字. 2、每次操作相当从总和 s中减去(a+b)-|a-b| ,
  即-2b或-2a(a>b和a<b) 3、由上2步可以确定剩余的数据是一个奇数(1<=m<=49) 4、接下来验证是不是每个奇数都可能被剩下:
  那我们先把m拿出来(r=s-m),其他经过n操作为0即可。 一样的道理 经n次操作 后 黑板上剩下0。即2(a1+b2+b3.....an)=r
  因为s为奇数减去一个奇数m。即r肯定为偶数。 那是求证在除m外的数据中存在和加起来为r/2的情况,如果存在,说明m可以被剩下。

代码:

    private static List<Integer> whatLeave(int n) {
        List<Integer> leaveNumList = new ArrayList<Integer>();
        int sum = n * (n + 1) / 2;
        int leavNum = 0;
        if (sum % 2 == 0) {//偶数           
            leavNum = 0;
        } else {//奇数
            leavNum = 1;
        }
        for (; leavNum <= n; leavNum += 2) {
            if (isBeLeav(n, leavNum, sum)) {
                leaveNumList.add(leavNum);
            }
        }


        return leaveNumList;


    }


    private static boolean isBeLeav(int n, int leavNum, int sum) {
        int otherSum = sum - leavNum;//因为1、sum为偶数,leavNum则为偶数,2、sum为奇数,leavNum则为奇数,所以 other肯定为偶数
        //因为要保证leavNum被留下,那其他的n-1个数 经若干次操作后只剩下0
        //所以存在一下关系:2(a1+b2+b3.....an)=otherSum
        int k = otherSum / 2;
        return isExistSomeNumSumEqualK(n, leavNum, k);


    }


    private static boolean isExistSomeNumSumEqualK(int n, int leavNum, int k) {
        int sum = 0;
        while (n > 0) {
            if (n == leavNum) {
                n--;
            }
            if (sum + n == k) {
                return true;
            } else if (sum + n < k) {
                sum = sum + n;
            }
            n--;
        }


        return false;
    }
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值