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

原题
题目描述
在这里插入图片描述
样例
输入

2
5 4
3 3

输出

8
4 4 4 4 1 1 1 1
3
3 3 3

思路
首先在比赛上,我们想到了一种暴力的方法。我们构造出两个数组,分别存储 m m n n n n m m ,然后逐一比对。比对时去长度较小的序列,在同一位进行相间的操作,减完为 0 0 的数组位置上有下一位来填充,直至两个数组中都没有数字,答案就是每一次相减的最小值。举个例子:
m = 10 m=10 n = 8 n=8

构造:a数组存储m个n,b数组存储n个m,c数组存储答案,ans存储口罩盒数
a[]={8 8 8 8 8 8 8 8 8 8}
b[]={10 10 10 10 10 10 10 10}
c[]={}
ans=0
相减1次:
a[]={8 8}
b[]={2 2 2 2 2 2 2 2}
c[]={8 8 8 8 8 8 8 8}
ans=8
相减2次:
a[]={6 6}
b[]={2 2 2 2 2 2}
c[]={8 8 8 8 8 8 8 8 2 2}
ans=10
相减3次:
a[]={4 4}
b[]={2 2 2 2}
c[]={8 8 8 8 8 8 8 8 2 2 2 2}
ans=12
相减4次:
a[]={2 2}
b[]={2 2}
c[]={8 8 8 8 8 8 8 8 2 2 2 2 2 2}
ans=14
相减5次:
a[]={}
b[]={}
c[]={8 8 8 8 8 8 8 8 2 2 2 2 2 2 2 2}
ans=16
输出:
16
8 8 8 8 8 8 8 8 2 2

比赛时就已经用这种方法 A C AC 了,赛后听老师讲过以后,却发现这过程竟然和辗转相除法惊人得相似。所以直接用减法代替取余存下来即可。
代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int t,n,m,cnt,a[maxn];
int main()
{
    for(scanf("%d",&t);t--;cnt=0)
	{
        scanf("%d%d",&n,&m);
        while(n>0)
		{
            if(n<m)n^=m^=n^=m;//交换,相当于swap(n,m);
            for(int i=1;i<=m;++i)a[++cnt]=m;
            n-=m;
        }
        printf("%d\n",cnt);cnt++;
        for(int i=1;i^cnt;i++)printf("%d ",a[i]);//相当于i从1到cnt
        printf("\n");
    }
}

猜你喜欢

转载自blog.csdn.net/bbbll123/article/details/107747216
今日推荐