原题
题目描述
样例
输入
2
5 4
3 3
输出
8
4 4 4 4 1 1 1 1
3
3 3 3
思路
首先在比赛上,我们想到了一种暴力的方法。我们构造出两个数组,分别存储
个
和
个
,然后逐一比对。比对时去长度较小的序列,在同一位进行相间的操作,减完为
的数组位置上有下一位来填充,直至两个数组中都没有数字,答案就是每一次相减的最小值。举个例子:
当
,
时
构造: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
比赛时就已经用这种方法
了,赛后听老师讲过以后,却发现这过程竟然和辗转相除法惊人得相似。所以直接用减法代替取余存下来即可。
代码
#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");
}
}