题意比较容易理解,不解释了。
会的两种解法
(1)找所有工厂效率的最小公倍数,再以最小公倍数除以时间的和作为最少人数,看m是否为最小人数整数倍即可
代码如下:
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
int t;
if(a<b)
{
t=a;
a=b;
b=t;
}
if(a%b==0)
return b;
else
return gcd(b,a%b);
}
int gce(int a,int b)
{
return (a*b)/gcd(a,b);
}
int main()
{
int n;
ll m;
ll ans=0;
int a[1010];
int b=1;
ll ant=0;
scanf("%d%lld",&n,&m);
// printf("%d %lld",n,m);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
ans+=a[i];
// printf("%d\n",a[i]);
b=gce(b,a[i]);
// printf("b : %d\n",b);
}
for(int i=0;i<n;i++)
{
ant+=b/a[i];
}
if(m%ant!=0)
printf("No\n");
else
{
printf("Yes\n");
for(int i=0;i<n;i++)
{
if(!i)
printf("%lld",(m/ant)*(b/a[i]));
else
printf(" %lld",(m/ant)*(b/a[i]));
}
printf("\n");
}
return 0;
}
(2)二分,左边界 l=0,右边界 r=max(a[i])*m;
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
long long n,m;
int a[10010];
double abc(long long x)
{
double sam=0;
for(int i=0;i<n;i++)
{
sam+=(x/a[i]);
}
return sam;
}
int main()
{
while(cin>>n>>m)
{
long long r,l,mod;
double ant;//ant为long long类型也对
long long res=0;
bool flag=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]>res)
res=a[i];
}
r=res*m;
l=0;
while(l<=r)
{
mod=(l+r)/2;
ant=abc(mod);
// for(int i=0;i<n;i++)
// {
// ant+=(mod/a[i]);
// }
if(ant<m)
l=mod+1;
else if(ant>m)
r=mod-1;
else
{
flag=1;
break;
}
}
if(flag)
{
cout<<"Yes"<<endl;
cout<<mod/a[0];
for(int i=1;i<n;i++){
cout<<" "<<mod/a[i];
}
cout<<endl;
}
else{
cout<<"No"<<endl;
}
}
return 0;
}
/*
2 6
1 2
2 5
1 2
*/