【CCPC-2019】【江西省赛】【霖行】J-Worker

【CCPC-2019】【江西省赛】【霖行】J-Worker

题目:

Avin meets a rich customer today. He will earn 1 million dollars if he can solve a hard problem. There are n warehouses and m workers. Any worker in the i-th warehouse can handle a_i orders per day. The customer wonders whether there exists one worker assignment method satisfying that every warehouse handles the same number of orders every day. Note that each worker should be assigned to exactly one warehouse and no worker is lazy when working.

Input

The first line contains two integers n (1 ≤ n ≤ 1, 000), m (1 ≤ m ≤ 10^18). The second line contains n integers. The i-th integer a_i (1 ≤ a_i ≤ 10) represents one worker in the i-th warehouse can handle a_i orders per day.

Output

If there is a feasible assignment method, print “Yes” in the first line. Then, in the second line, print n integers with the i-th integer representing the number of workers assigned to the i-th warehouse. Otherwise, print “No” in one line. If there are multiple solutions, any solution is accepted.

Sample Input

2 6
1 2
2 5
1 2

Sample Output

Yes
4 2
No

题目大意:

公司有n个仓库,m个工人。在第i个仓库中,每个工人能完成a_i个订单。每个仓库不限工人数量,工人的工作效率只受仓库影响。

问:有没有可能合理分配工人,使所有仓库每天完成的总订单数相同?

输入样例:
第一行给出两个整数n,m。表示有n个仓库,m个工人。
第二行给出n个整数,第i个整数代表第i个仓库中每个工人每天能完成的订单数量。

输出样例:
如果能合理分配工人,使所有仓库每天完成的总订单数相同。就在一行中输出Yes,并且在第二行中给出每个仓库应该有多少个工人。
如果不能合理分配工人,只要在一行中输出No。

样例分析:

题目给出了两组样例

第一组:

Input
2 6
1 2
Output
Yes
4 2

总共有两个仓库,6个工人。第一个仓库中,每个工人每天能完成1个订单。第二个仓库中,每个工人能完成2个订单。

存在方案:第一个仓库分配4个工人,每天总共可完成4个订单。第二个仓库分配2个工人,每天总共可完成4个订单。

故输出Yes, 4, 2。

题目分析:

我们可算出每个仓库工人效率共同的最小公倍数lcm,lcm即每个仓库共同的最小总单数。

lcm/(每个仓库工人的效率) 就是每个仓库所需要的最小人数。

将每个仓库所需的最小人数相加,就是存在目标方案的最小总工人数sum。

若总工人数为sum的倍数,那么就存在方案。

代码:

#include
using namespace std;
//计算最大公约数
long long gcd(long long a, long long b)
{
     
	return b == 0 ? a : gcd(b, a % b);
}
//计算最小公倍数
long long lcm(long long a, long long b)
{
     
	return a / gcd(a, b) * b;
}

int main()
{
     
	long long n, m;
	while (cin>>n>>m)
	{
     
        //A为仓库工人效率,B为仓库应有工人的最小数量
		long long A[11111] = {
      0 };
		long long B[11111] = {
      0 };
        //计算最小公倍数
		long long GBS = 1;
		for (int i = 0; i < n; i++)
		{
     
			scanf("%lld", &A[i]);
			GBS = lcm(GBS, A[i]);
		}
		//计算所需最小总工人数
		long long sum = 0;
		for (long long i = 0; i < n; i++)
		{
     
			B[i] = GBS / A[i];
			sum += B[i];
		}
        //不符合条件
		if (m % sum != 0)
		{
     
			printf("NO\n");
			continue;
		}
        //符合条件
		printf("Yes\n");
		for (long long i = 0; i < n; i++)
		{
     
			if (i != 0) printf(" ");
			printf("%lld", B[i]*(m / sum));//(m/sum)为倍数
		}
		puts("");
	}
	return 0;
}

你可能感兴趣的:(题解,c++)