洛谷普及B3754 [信息与未来 2019] 鸡兔同笼

题目:[信息与未来 2019] 鸡兔同笼

题号:B3754

难度:普及一


题目分析

在原始的鸡兔同笼基础上,加入了三脚猫变量,让整体的灵活性提升,

但实际上基础逻辑并没有太大转变,整体分析起来还是挺舒服的。

题目要求在给出头和脚的数量情况下,求出兔子的最大最小数量。

思路

给出参数 head 和 leg

假设全是鸡,得到腿脚数量   leg_chick = 2*head.

假设全是三脚猫,得到腿脚数量   leg_cat = 3*head.

假设全是兔子,得到腿脚数量   leg_rabbit = 4*head.

如果  leg = leg_chick  很显然 全是鸡,则chick_n = head  cat_n = 0  rabbit_n = 0

如果  leg_chick < leg <= let_cat  ,其中多的腿数,是多腿动物与鸡的差值决定。

每多一条腿,都可以是三脚猫的,每多两条腿就可能是兔子的。

此时也可以没有兔子,因为在leg <= let_cat 的情况下,多余的腿可以只用三脚猫来补齐。

所以此时rabbit_min = 0;

而兔子的最大数量,取决于多与leg_chick的腿数,每多两条就可以有一个兔子,如果是奇数的话,例如多三条,则是一只兔子和一只三脚猫一起来补齐,所以用多的腿数除于二,向下取整,就是兔子的最大数量,由于C语言整数的自动向下取整,所以只需rabbi_max = (leg - leg_chick)/2;

最后一种情况就是

leg_cat < leg <= leg_rabbit  ,此时由于腿的数量大于全是猫的数量,所以一定存在兔子,

且兔子的最少数量 rabbit_min =  leg - leg_cat ,因为三脚猫与兔子差一只脚。

此时的rabbi_max = (leg - leg_chick)/2;与上一种情况保持一致。

数量关系

再说的直接一些可以是,有以下关系。

//本来有t个头,x只脚 (x>=2*t)

//x==2*t时,全是鸡

//x>2*t时,一定存在除了鸡之外的动物

//对于 x - 2*t 只脚,则多在三脚猫和兔子身上

//如果,2*t<x<=3*t,则可以没有兔子,(兔子min=0)只使用三脚猫也能补齐剩下的腿。

//如果,2*t<x<=3*t,也可以有兔子,(兔子max=(x-2*t)/2向下取整)(然后三只猫补齐剩下的腿)

//如果,3*t<x<=4*t,只有三脚猫就不够了,

// 一定存在兔子补齐剩下的腿。且(兔子min=x-3*t)(兔子max=(x-2*t)/2向下取整)

代码函数

用两个函数,利用上述思路分析的关系分别输出兔子的最小值和最大值

(其中后两种情况的最大值关系计算相同,所以合并为一种)

long long rabbit_max(long long h,long long x){
long long max;
if(x<=2*h) return 0;
return (x-2*h)/2;
}
long long rabbit_min(long long h,long long x){
if(x<=3*h) return 0;
else return x-3*h;
}

由于本题是计算不同组的结果,所以我这里采用的是结构体的一维数组,

结构体中存储头和腿的数量

struct stu{
long long head;
long long leg;
}a[22];

总代码

//本来有t个头,x只脚 (x>=2*t)
//x==2*t时,全是鸡
//x>2*t时,一定存在除了鸡之外的动物
//对于 x - 2*t 只脚,则多在三脚猫和兔子身上
//如果x是奇数,则一定有三脚猫的存在。
//如果,2*t<x<=3*t,则可以没有兔子,(兔子min=0)只使用三脚猫也能补齐剩下的腿。
//如果,2*t<x<=3*t,也可以有兔子,(兔子max=(x-2*t)/2向下取整)(然后三只猫补齐剩下的腿)
//如果,3*t<x<=4*t,只有三脚猫就不够了,
// 一定存在兔子补齐剩下的腿。且(兔子min=x-3*t)(兔子max=(x-2*t)/2向下取整)

#include <stdio.h>

struct stu{
long long head;
long long leg;
}a[22];

long long rabbit_max(long long h,long long x){
long long max;
if(x<=2*h) return 0;
return (x-2*h)/2;
}
long long rabbit_min(long long h,long long x){
if(x<=3*h) return 0;
else return x-3*h;
}

int main() {
int T;
scanf("%d",&T);
for(int i=1;i<=T;i++)
scanf("%lld %lld",&a[i].head,&a[i].leg);
for(int i=1;i<=T;i++){
long long max=rabbit_max(a[i].head,a[i].leg);
long long min=rabbit_min(a[i].head,a[i].leg);
printf("%lld %lld\n",min,max);
}


return 0;
}

总结

本题通过引入三脚猫这一新的变量来赋予本题更大的灵活性,但是基础逻辑并未有实质性改变,总体来说,分析的时候很清晰,思路抒清,会很舒服。难度偏易。某种意义上来说,本题更偏向是一道数学题。

为什么这样说,因为甚至使用线性规划都能写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LAOLONG-C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值