东华大学2020考研计算机OJ题目解答分享——进阶篇(64)

问题描述 :

农夫约翰从来只用调配得最好的饲料来为他的奶牛。

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

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

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

1:2:3

3:7:1

2:1:2

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

对于上面的例子,你可以用8份饲料1,2份饲料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。一种混合物的比例不会由其他混合物的比例直接相加得到。

输入说明 :

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

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

输出说明 :

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

输入范例 :

3 4 5
1 2 3
3 7 1
2 1 2

输出范例 :

8 1 5 7

解答思路:

	刚看到题目觉得很简单,和前面一道三角形个数题目类似遍历一遍即可。
	第一遍提交ac了一半,看了错误的测试用例发现时忽略了除数为0的情况。这题不考
虑0相当简单,带上0还是挺麻烦的因为一开始判别成比例是用的sumx/x==sumy/y,不好
确认哪一项为0。最后只能开了个函数判断前三个数和后三个数是否成比例倍数关系。
在解答这道题的过程中还有几个比较值得注意的点:
		1 注意数据类型,sumx、y、z需要用double型不然会有7/3==9/4==11/5这种
错误。
		2 for循环判别条件处加上总袋数限制大小,可以省去一大半时间,要是饲料A
的袋数就大于前一种方案的总袋数,就没有继续的意义了。
		3 新开的函数内部还应该考虑abc其中两者或三者同时为0的情况。为了省时间
先写了一个0的情况提交试了下就ac了然后就没补齐。

由于写的比较赶时间,用了暴力的方法。如果有更好的思路恳请指教。

AC代码

#include <cstdio>
#include <cstring>
/**
*函数rule判别xyz与abc是否成比例关系,返回倍数。 
*/ 
int rule(double x,double y,double z,int a,int b,int c)
{
	
	if(a!=0&&b!=0&&c!=0)
	{
		if((x/a==y/b)&&(y/b==z/c))
		return int(x/a);
		else
		return 0;
	}
	else if(a==0&&b!=0&&c!=0)
	{
		if((y/b==z/c)&&x==0)
		return int(y/b);
		else
		return 0;
	}
	else if(a!=0&&b==0&&c!=0)
	{
		if((x/a==z/c)&&y==0)
		return int(x/a);
		else
		return 0;		
	}
	else if(a!=0&&b!=0&&c==0)
	{
		if((y/b==x/a)&&z==0)
		return int(y/b);
		else
		return 0;
	}
	
}

int main(){
	int x,y,z;
	scanf("%d %d %d",&x,&y,&z);
	int a[3][3];
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	
	int minsum=999;
	int mini,minj,mink,times;
	
	int beishu=0;
	for(int i=0;i<100&&i<minsum;i++)
	{
		for(int j=0;j<100&&i+j<minsum;j++)
		{
			for(int k=0;k<100&&i+j+k<minsum;k++)
			{
				double temx=double(i*a[0][0]+j*a[1][0]+k*a[2][0]);
				double temy=double(i*a[0][1]+j*a[1][1]+k*a[2][1]);
				double temz=double(i*a[0][2]+j*a[1][2]+k*a[2][2]);
				times=rule(temx,temy,temz,x,y,z);
				if(times)
				{
			
					int sum=i+j+k;
					if(sum<minsum)
					{
						minsum=sum;
						mini=i;minj=j;mink=k;
					    beishu=times;
					}
				}
				
			}
		}
	}
	
	if(minsum==999)
	{
		printf("NONE");
	}
	else
	{
		printf("%d %d %d %d",mini,minj,mink,beishu);
	}
	

	
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值