Worker HDU - 6576

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 ai 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 ai (1 ≤ ai ≤ 10) represents one worker in the i-th warehouse can handle ai 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

译文:
Avin今天遇到了一位富有的客户。如果他能解决一个难题,他将赚一百万美元。有n个仓库和m个工人。在i-th仓库的任何工人每天都可以处理人工智能订单。客户想知道是否有一种工人分配方法可以满足每个仓库每天处理相同数量的订单。请注意,每个工人应该被精确地分配到一个仓库,并且在工作时没有工人是懒惰的。
Input:第一行包含两个整数n(1≤n≤1000),m(1≤m≤10^18)。第二行包含n个整数。第i个整数ai(1≤ai≤10)表示第i个仓库中的一个工人每天可以处理ai订单。

分析

要使每个仓库的总订单数相等,即每个仓库的a_i * b_i(b_i为工人数)相等。
易知,订单数是所有a[i]的公倍数。可以先求出最小公倍数s,让sum+=s/a[i],得出sum就是最小的工人数量。只有m%sum==0 才输出yes。

import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Vector;

public class Main{
	static int N=(int)1e3+1;
	
	
	public static void main(String[] args)throws IOException {
		Scanner sc=new Scanner(System.in);
		
		int n;
		long m;
		int []a=new int [N];
		int []b=new int [N];
		while(sc.hasNext()) {
			n=sc.nextInt();m=sc.nextLong();
			for(int i=1;i<=n;i++) {
				a[i]=sc.nextInt();
				b[i]=a[i];
			}
			Arrays.sort(a,1,n+1);
			int s=a[1];
			for(int i=2;i<=n;i++) {
				if(s%a[i]!=0)
					s=lcm(s,a[i]);
			}
			int sum=0;
			for(int i=1;i<=n;i++) {
				sum+=s/b[i];
			}
			if(m%sum==0) {
				System.out.println("Yes");
				long k=m/sum;
				for(int i=1;i<n;i++) System.out.print(k*s/b[i]+" ");
				System.out.println(k*s/b[n]);
			}else {
				System.out.println("No");
			}
		}
	}
	
	static int lcm(int a,int b) {
		int r;
		if(a>b) {
			r=a;a=b;b=r;
		}
		int s=1;
		for(int i=2;i<=a&&i<=b;i++) {
			if(a%i==0&&b%i==0) {
				a/=i;b/=i;s*=i;i=1;
			}
		}
		return a*b*s;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值