口罩生产

口罩生产

  1. 题目描述
    问题描述
    众所周知,口罩是2020年炙手可热的年货,在你反应过来的时候口罩已经脱销了。
    此时,你家小区规定没有佩戴口罩者不许出门。为了能顺利出门购买生活必需品,你必须自己想办法做一些能通过社区大妈检验的合格口罩。
    已知:
    1、制作一个合格的口罩需要a块无纺布,b条尼龙绳,以及防护口罩的核心——c块熔喷布。
    2、此时你手上刚好有n件无纺布、m条尼龙绳、以及r块熔喷布。
    3、因为你的手上还有p克制作这三件物品的原料——聚丙烯,因此你可以分别消耗x、y、z克聚丙烯来制作无纺布、尼龙绳以及熔喷布。
    请问你最多能做出几个口罩?
    数据输入
    输入有4行,其中:
    第一行有三个整数a、b、c,表示口罩制作需要的无纺布、尼龙绳与熔喷布的数量
    第二行有三个整数n、m、r,表示你现有的无纺布、尼龙绳与熔喷布的数量
    第三行有一个整数p,表示你现有的聚丙烯的重量总和(单位:克)
    第四行有三个整数x、y、z,表示制作无纺布、尼龙绳与熔喷布需要的聚丙烯重量(单位:克)
    数据输出
    输出一个整数,表示你可制作的合格口罩数量。
    输入示例
    3 2 1
    6 4 1
    4
    1 2 3
    输出示例
    2
    数据范围
    1、0 ≤ a,b,c ≤ 100,且有 0 < a+b+c ≤ 100
    2、1 ≤ n,m,r ≤ 100
    3、1 ≤ p ≤ 1e12
    4、1 ≤ x,y,z ≤ 100
    Hit
    友情提示:口罩购买请认准正规厂家生产的合格口罩XD。
  2. 第一次分析
    参考csdn大佬的一个做法:类似俄罗斯方块,(木桶短板),先消去,聚丙烯先转换为最最短板的原材料。
    参考描述:

来自江心之人

组装玩具(贪心)

  1. 第一次代码
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 4;
struct node 
{
	ll x;
	ll y;
	ll z;
	ll m;
} ;
int cmp(node a, node b)
{
	return (a.m < b.m);
}
void judge(ll p,int n);
node a[N]; 
int main()
{
	int p;
	int num=0;    //记录0个数 
	for (int i = 1; i <=3; i++) 
	{
		cin >> a[i].x;
		if (a[i].x!=0)
		num++;
	}
	for (int i = 1; i <=3; i++) 
	{
		cin >> a[i].y;
		if (a[i].x!=0)
		a[i].m = llabs(a[i].y / a[i].x);
		//cout<<"a["<<i<<"].m="<<a[i].m<<endl;
		
	}
	cin>>p;
	for (int i = 1; i <=3; i++) 
	{
		cin >> a[i].z;
	}
	if(num<3)
	{
		node X[num+1];
		int j=1;
		for(int i=1;i<=3;i++)
		{
		
			if(a[i].x!=0)
			{
				X[j].x=a[i].x;
				X[j].y=a[i].y;
				X[j].z=a[i].z;
				X[j++].m=a[i].m;
				
			}
			
		}
		for(int i=1;i<=num;i++)
		{
		a[i].x=X[i].x;
		//cout<<"a["<<i<<"].x="<<a[i].x<<endl;
		a[i].y=X[i].y;
		a[i].z=X[i].z;
		a[i].m=X[i].m;
		//cout<<"a["<<i<<"].m="<<a[i].m<<endl;	
		}
		sort(a+1, a + num+1, cmp);
		judge(p,num);
		ll ans=a[1].m ;
		for (int i = 1; i <= num; i++)
		{
			ans = min(ans, a[i].m);
		}
		cout << ans << endl;
		return 0;	
	}
	sort(a+1, a + 4, cmp);//结构排序 短板在前 
	judge(p,3);
	ll ans=a[1].m ;
	for (int i = 1; i <= 3; i++)
		{
			ans = min(ans, a[i].m);
		}
	cout << ans << endl;
	return 0;
			
}

void judge(ll p,int n)
{
	int ok = 1;
	while (p > 0 && ok)
	{
		int mod = 0;
		for (int i = 1; i <= n; i++) 
		{
			
			cout <<"i="<<i<<endl;
			if (i > 1 && a[i].m != a[i - 1].m - 1) break;//三种原料不等时退出循环,少的先增加数量。 
			mod += a[i].y % a[i].x;
			//cout<<"mod="<<mod<<endl;
			ll need = a[i].x - (a[i].y % a[i].x);//所缺原料数量 
			//cout<<"need="<<need<<endl;
			if (p >= need*a[i].z) 
			{
				a[i].y += need;
				a[i].m++; 
				//cout<<"a["<<i<<"].m="<<a[i].m<<endl;             //满足,短板+1 
				p -= need*a[i].z;      //万能原料减少 
				//cout<<"p="<<p<<endl;
			}
			else 
			{
				ok = 0;            //万能材料不足            
				break;
			}
		}
	}
}

说明:当然结果有些数据点过不了,哈哈

  1. 第二次分析
    向某位大佬询问了下,突然明白这个问题可以反过来思考,先把现有的材料生产出口罩,不够的用聚丙烯补齐,剩下的聚丙烯直接去生产口罩,这个问题就变得简单明了了。(在此谢过这位大佬)

  2. 第二次代码

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 4;
ll sum1=0,sum2 =0,sum0=0;
struct node 
{
	ll x;   
	ll y;
	ll z;
	ll m;
} a[N];
ll Max;
ll Min;
int main()
{
	ll p;
	for (int i = 1; i <=3; i++) 
	{
		cin >> a[i].x;    
	}
	for (int i = 1; i <=3; i++) 
	{
		cin >> a[i].y;    
	}
	cin>>p;                      
	for (int i = 1; i <=3; i++) 
	{
		cin >> a[i].z;           
		if(a[i].x!=0)
		{
            sum1+=a[i].x*a[i].z;
			a[i].m = a[i].y/a[i].x;
		}
	}
	int i ;
	for( i =1 ;i<N;i++)
	{
		if(a[i].x!=0)
		{
			Min = Max = a[i].m;
			break;
		}
	}
	for(++i;i<N;i++)
	{
		if(a[i].x!=0)
		{
			Min = min(Min,a[i].m);
			Max = max(Max,a[i].m);
		}
	}
	for(i = 1;i<N;i++)
	{
		if(a[i].x!=0)
		sum0+=(Max*a[i].x-a[i].y)*a[i].z;
	}
	if(p<sum0)
	{
		cout<<Min<<endl;
		return 0;
	}
	else 
	{
		p = p-sum0;
		ll ans;
		ans=p/sum1 +Max;
		cout<<ans<<endl;
		return 0;
	}
}

新手,勿喷。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值