牛客暑期多校训练营(第七场) B Mask Allocation 补题

题目:
Nowadays, the Kingdom of Dreamgrid is suffering from a national pandemic. Fortunately, president Baobao is working effectively with the Center for Disease Control (CDC) and they are trying their best to make everything under control.

President Baobao has received n \times mn×m medical masks from his friend Reku, an extremely rich billionaire. As the chief of the CDC, you are required to allocate these masks properly. There are 2 kinds of hospitals in the Kingdom of Dreamgrid, n senior hospitals for critically ill patients and m mobile cabin hospitals for patients with mild symptoms.

Before allocating them to hospitals, you have to pack them into boxes. Please note that boxes must not be opened in order to prevent contamination and you only know these boxes will be allocated to either senior hospitals or mobile cabin hospitals. That is to say, there should be a way of dividing masks boxes into m groups of n masks, and a way of dividing into n groups of m masks.

You want the number of boxes to be minimal and please also provide a lexicographically greatest sequence of the numbers of masks in boxes. We say a sequence a is lexicographically greater than another b of the same length if there exists an integer i, such that

aj=bj, for all j < i; and
ai>bi;

题意:有n*m个面具,k个盒子,要求盒子装的能组合出n个m,也能组合出m个n,求k最小值。

思路:
1)令m大n小,构造n^ 2个n,现在问题转化为剩下mn-n^2,要求既能组合出m-n个n,也能组合出n个m-n,比如,m=5,n=3, 先{3,3,3},问题转换成m=2,n=3,不符合m>n,所以m=3,n=2,数组变成{3,3,3,2,2},现在m=1,n=2,同上一步调换,所以m=2,n=1,数组变成{3,3,3,2,2,1},m=1,n=1,数组变成{3,3,3,2,2,1,1},这样k=7,数组为{3,3,3,2,2,1,1}。既可以{3,3,3,(2+1),(2+1)},也可以{(3+2),(3+2),(3+1+1)}.
2)怎么去想到上面这个解题思路呢:首先我们手上有n
m,m>n,我们能装进盒子的最大不能超过n,否则不能满足组合出m个n,最多我们能放几个这样的盒子呢? n*n个,再多的话可能会不满足n个m,那m=5,n=3来说,按照思路1,我们能得到333,如果非要分成3333,剩下的就都按111来处理,则数组为{3,3,3,3,1,1,1},那为了满足3个5,我们先拿3个3当基底,然后加到5,则会出现第四个3无处安放的局面。

所以!

总的来说,一个盒子里的最大面具数由n制约(为了满足m个n),而装多少个最多面具(n)的盒子由m制约(为了满足n个m)
下面贴ac代码

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while (t--)
    {
        int n,m;
        cin>>n>>m;//n小m大
        if(n>m) swap(n,m);
        vector<int> v;
        while (1)
        {
            for(int i=0;i<n;i++)
            v.push_back(n);
            m-=n;
            if(m*n==0) break;
            if(n>m) swap(n,m);
        }
        printf("%d\n",v.size());
        for(int i=0;i<v.size();i++)
            printf("%d ",v[i]);
        cout<<endl;
    }
    return 0;
}

感谢观看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值