Feed Ratios_usaco3.2_暴力

本文介绍了一个饲料比例调配问题的解决方案,通过枚举不同饲料组合找到能够最接近目标饲料比例的配方。该问题需要处理多种原料比例,并确保最终混合饲料的比例符合特定要求。

题目描述 Description


农夫约翰从来只用调配得最好的饲料来喂他的奶牛。饲料用三种原料调配成:大麦,燕麦和小麦。他知道自己的饲料精确的配比,在市场上是买不到这样的饲料的。他只好购买其他三种混合饲料(同样都由三种麦子组成),然后将它们混合,来调配他的完美饲料。

给出三组整数,表示 大麦:燕麦:小麦 的比例,找出用这三种饲料调配 x:y:z 的饲料的方法。

例如,给出目标饲料 3:4:5 和三种饲料的比例:

1:2:3
3:7:1
2:1:2
你必须编程找出使这三种饲料用量最少的方案,要是不能用这三种饲料调配目标饲料,输出“NONE”。“用量最少”意味着三种饲料的用量(整数)的和必须最小。

对于上面的例子,你可以用8份饲料1,1份饲料2,和5份饲料3,来得到7份目标饲料:

8*(1:2:3) + 1*(3:7:1) + 5*(2:1:2) = (21:28:35) = 7*(3:4:5)
表示饲料比例的整数以及目标饲料的都是小于100的非负整数。表示各种饲料的份数的整数,都小于100。一种混合物的比例不会由其他混合物的比例直接相加得到。

输入描述 Input Description


Line 1: 三个用空格分开的整数,表示目标饲料

Line 2..4: 每行包括三个用空格分开的整数,表示农夫约翰买进的饲料的比例

输出描述 Output Description


输出文件要包括一行,这一行要么有四个整数,要么是“NONE”。前三个整数表示三种饲料的份数,用这样的配比可以得到目标饲料。第四个整数表示混合三种饲料后得到的目标饲料的份数。

题解 Analysis


暴力出奇迹

枚举三种配料的比值,注意一下有0的情况就可以了
正解是线性方程?

代码 Code


/*
ID:wjp13241
PROG:ratios
LANG:C++
*/
#include <stdio.h>
using namespace std;
struct feed
{
    long long a,b,c;
    feed operator *(int x)
    {
        return (feed){a*x,b*x,c*x};
    }
    feed operator +(feed x)
    {
        return (feed){a+x.a,b+x.b,c+x.c};
    }
    bool operator ==(feed x)
    {
        if (a&&b&&c)
            return x.a/a==x.b/b&&x.c/c==x.b/b&&x.a/a*a==x.a&&x.b/b*b==x.b&&x.c/c*c==x.c;
        if (!a&&b&&c)
            return x.c/c==x.b/b&&x.b/b*b==x.b&&x.c/c*c==x.c;
        if (a&&!b&&c)
            return x.c/c==x.a/a&&x.a/a*a==x.a&&x.c/c*c==x.c;
        if (a&&b&&!c)
            return x.a/a==x.b/b&&x.a/a*a==x.a&&x.b/b*b==x.b;
    }
}t[4];
int main()
{
    freopen("ratios.in","r",stdin);
    freopen("ratios.out","w",stdout);
    for (int i=0;i<4;i++)
        scanf("%d%d%d",&t[i].a,&t[i].b,&t[i].c);
    for (int i=0;i<=100;i++)
        for (int j=0;j<=100;j++)
            for (int k=0;k<=100;k++)
            {
                if ((i==j)&&(i==k)&&(k==j)&&(!i))
                    continue;
                feed tmp=(t[1]*i)+(t[2]*j)+(t[3]*k);
                if (t[0]==tmp)
                {
                    int v=tmp.a?tmp.a/t[0].a:v;
                    v=tmp.b?tmp.b/t[0].b:v;
                    v=tmp.c?tmp.c/t[0].c:v;
                    printf("%d %d %d %d\n",i,j,k,v);
                    return 0;
                }
            }
    printf("NONE\n");
    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值