列表

详情


WY79. 分贝壳

描述

牛牛和妞妞去海边捡了一大袋美丽的贝壳,千辛万苦地运回家后,牛牛和妞妞打算分掉这些贝壳。
牛牛提出,他和妞妞轮流从还没有分配的贝壳中取一定数量的贝壳,直到贝壳分完为止。分配规则是牛牛每次取剩余贝壳的1/10(向下取整),妞妞每次固定取m个贝壳,妞妞先取。
妞妞想要得到不少于一半的贝壳,又不想太过分,那么她一次最少取多少个贝壳才能得到不少于一半的贝壳呢?

输入描述

一个正整数n,表示贝壳的总数量,1<=n<=1000000000000000000。

输出描述

一个正整数m,表示妞妞一次最少取的贝壳数量。

示例1

输入:

10

输出:

1

示例2

输入:

70

输出:

3

原站题解

C 解法, 执行用时: 2ms, 内存消耗: 336KB, 提交时间: 2021-10-17

#include <stdio.h>

int main()
{
	long long int n;
	scanf("%lld", &n);
	long long int right = n / 10; //右边界。
	long long int left = 1; //左边界。
	int flag = 0;
	long long int T = 0;
	long long int m = left+(right-left)/2;
	while (1)
	{
		long long int a = 0; //牛牛得到的贝壳。
		long long int b = 0; //妞妞得到的贝壳。
		long long int res = n;
		while (1)
		{
			res -= m; //牛牛取完后剩余的贝壳数。
			b += m;
			a += res / 10;
			res -= res / 10;
			//如果牛牛最后的贝壳数大于(n+1)/2,说明m小了。
			if (a > (n + 1)/2)
			{
				flag = 0;
				break;
			}
			//如果妞妞最后的贝壳数不小于(n+1)/2,说明m够了。
			if (b >= (n + 1) / 2)
			{
				flag = 1;
				break;
			}
		}
		if (flag == 0)
		{
			left = m + 1; //m不够,左边界变大。
			if(left > right)
			{
				m = T;
				break;
			}
			m = left + (right - left) / 2; //二分
		}
		//找到最小的m值
		else
		{
			T = m;
			right = m - 1;
			if (left > right)
			{
				break;
			}
			m = left + (right - left) / 2;
		}
	}
	printf("%lld", m);
	return 0;
}

C 解法, 执行用时: 2ms, 内存消耗: 336KB, 提交时间: 2021-09-16

#include<stdio.h>

int func(long n,long m)
{
    long s=n,boy=0,time=0;
    while(1)
    {
        time++;
        s-=m;
        if(time*m > (n/2))
        {
            return 1;
        }
        else
        {
            long temp = s/10;
            boy += temp;
            s -= temp;
            if(boy>(n/2))
            {
                return 0;
            }
        }
    }
}

int main()
{
    long num=0;
    while(scanf("%ld",&num)!=EOF)
    {
        long low = 1,high = num,mid = (low+high)/2;
        while(1)
        {
            if(func(num,mid) == 1)
            {
                if(func(num,mid-1) == 0)
                {
                    printf("%ld\n",mid);
                    break;
                }
                high = mid;
                mid = (low+high)/2;
            }
            else if(func(num,mid) == 0)
            {
                if(func(num,mid+1) == 1)
                {
                    printf("%ld",mid+1);
                    break;
                }
                low = mid;
                mid = (low+high)/2;
            }
        }
    }
    return 0;
}

上一题