腾讯云智笔试算法题——分苹果

877 阅读2分钟

有m个苹果,n个小孩。每个小孩都有一个编号,小明的编号是k。要尽量公平的分苹果,相邻编号的小孩分到的苹果数目差距不能大于1。
请问如何在满足相邻编号的小孩分到的苹果数目差距不能大于1的情况下,小明分配到的苹果数目最多,并且输出这个最大值,每个小朋友至少需分配到一个苹果。

输入描述
第一行输入三个整数。

输出描述
输出一行,表示小明分配到苹果个数的最大值。

示例 1
4 6 2
输出
2

说明

可以这样分配1 2 2 1。小明分配到了2个苹果。

代码如下(舍友给的思路和代码,有一个大佬舍友的感觉真好):

欢迎指正和贡献测试用例,因为平台关了不能验证是不是完全正确,但是感觉思路没有问题。

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int k = sc.nextInt();
        System.out.println(maxApplesFork(m,n,k));
    }
    public static int maxApplesFork(int m, int n, int k) {
        //m苹果、n人数、k小明所在位置
        if (k > n)
            return -1;//小明所在下标大于总人数
        int left = k - 1, right = n - k, used = n;
        //左边人数、右边人数、保证每人至少一个所使用的苹果数
        int lnum = 0, rnum = 0, i, count = 1;
        //左右边界(为了给小明苹果而给旁边两人苹果的个数)、每轮消耗的苹果数、小明的苹果数
        for (i = 1; i <= n && used <= m; ) {
            count++;
            used += i;
            if (used >= m) {//苹果不够直接return
                return used > m ? count - 1 : count;
            }
            i += lnum >= left ? 0 : 1;//防止越界
            i += rnum >= right ? 0 : 1;
            lnum++;//两边界
            rnum++;
        }
        return -1;
    }

思路讲解:

1.计算出小明左边和右边的人数和已经使用的苹果数(为了保证每个人有一个苹果)

2.定义左右边界(为了给小明一个苹果,我们必须给他左右两人各一个苹果)、每轮需要的苹果数量,和小明拥有的苹果数量。

3.循环来分苹果

        1)先给小明一个

        2) 使用的苹果数used+i(第一次给小明,不用给他左右两边的人)

        2)判断苹果够不够,不够或者刚够,返回结果

        3)判断是否到达左右边界。若小明左右还有人(未到达),则给小明左右各一个,然后继续扩大小明左右边界(因为给小明的左右+1后,下一轮给小明时得给他的左右,和左右的左右都+1,相当于左右边界扩大1)