【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 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 ≤ 1018). 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

题意:

公司有n个仓库和m个工人。在第i个仓库中,每个工人能完成a_i个订单。每个仓库不限工人数量,但是工人的工作效率会受到仓库的影响。
问:能否合理的分配每个工人,使得每个仓库一天的派单量相同。若能,输出分配方法

输入样例:

第一行给出两个整数n,m。(即告诉你有n个仓库和m个工人)
第二行给出n个整数,表示第i个仓库中每个工人每天能完成的订单数量。(也就是工人的工作效率会受到仓库的影响的数据)

输出样例:

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

思路:

根据仓库对于工人的影响给的比例来与工人人数比较。如果能最后能除尽,这符合,反之为no


代码(有误):

(这个题目样例可以通过,但是最后得到的是Wrong Answer)

#include <cstdio>
#include <iostream>

using namespace std;
int main ()
{
    int m,n;
    while(~scanf("%d%d",&n,&m) && n>=1&&n<=1000&&m>=1&&m<=1018)//cin>>n>>m;
    {
        int a[1005]={0};
        int i,t;
        for(i=1;i<=n;i++)
        { cin>>a[i]; }
        int min=a[1];
        for(i=1;i<=n;i++)
        {
            if(min>a[i]) min = a[i];
        }
        int sum = 0;
        for(i=1;i<=n;i++)
            sum+=a[i];
        if(sum%min==0)
        { sum=sum/min; }
        if(m%sum==0)
        {
            printf("Yes\n");
            int k = m/sum;
            for(i=n;i>=1;i--)
            {
                if(i==1)
                    printf("%d \n",a[1]*k);
                else
                    printf("%d ",a[i]*k);
            }
        }
        else printf("No\n");
     }
    return 0;
}

改进后代码:

题解:

算出每个仓库工人效率共同的最小公倍数lcm(每个仓库共同的最小总单数)
每个仓库工人效率共同的最小公倍数/每个仓库工人的效率)
就是每个仓库所需要的最小人数
代码如下:

#include<iostream>
using namespace std;
long long n, m;
long long p[1005];
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()
{
    while (cin >> n >> m)
    {
        for (long long i = 1; i <= n; i++)
            cin >> p[i];
        long long temp = p[1];
        for (long long i = 2; i <= n; i++)
        {
            temp = lcm(temp, p[i]);
        }

        long long cnt = 0, flag = 0, d;
        for (long long i = 1; i <= n; i++)
            cnt = cnt + temp / p[i];
        if (m%cnt != 0)
            flag = 1;
        else
            d = m / cnt;
        if (flag == 0)
        {
            cout << "Yes" << endl;
            for (long long i = 1; i <= n; i++)
            {
                if (i != n)
                    cout << temp / p[i] * d << ' ';
                else
                    cout << temp / p[i] * d << endl;
            }
        }
        else
            cout << "No" << endl;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZShiJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值