题意: 有
n
n
n个
A
A
A类医院,
m
m
m个
B
B
B类医院,共
n
×
m
n\times m
n×m个口罩。要你对这些口罩进行分箱,使得将所有口罩分给
A
A
A类医院时可以均分,将所有口罩分给
B
B
B类医院时也可以均分。
数据范围:
1
≤
n
,
m
≤
1
0
4
1\leq n,m\leq 10^4
1≤n,m≤104
题解: 设
n
≤
m
n\leq m
n≤m,那么一个箱子最多
n
n
n个口罩,否则若有某个箱子口罩数多于
n
n
n,当分给
B
B
B类医院时,必然存在某些医院分到多于
n
n
n个口罩,某些医院分到少于
n
n
n个口罩。
所以可以先分出来
n
n
n箱,每箱有
n
n
n个口罩。
之后:
- 对于分给 A A A类医院,还有 ( m − n ) (m-n) (m−n)个医院各需要 n n n个口罩。
- 对于分给 B B B类医院, n n n个医院还有需要 ( m − n ) (m-n) (m−n)个口罩。
可以发现这是一个子问题。考虑
g
c
d
(
a
,
b
)
=
g
c
d
(
a
,
b
−
a
)
,
b
≥
a
gcd(a,b)=gcd(a,b-a),b\geq a
gcd(a,b)=gcd(a,b−a),b≥a
所以循环一遍即可。
代码:
#include<bits/stdc++.h>
using namespace std;
/*
n < m
n个n
对于n个医院,还有n个医院还需要m-n个口罩
对于m个医院,还有(m-n)个医院需要n个口罩
*/
int main()
{
int T;
scanf("%d", &T);
while(T--) {
vector<int> ans;
int n, m;
scanf("%d%d", &n, &m);
if(n > m) swap(n, m);
while(n != 0) {
for(int i = 1; i <= n; i++) ans.push_back(n);
int m1 = m - n, m2 = n;
n = m1, m = m2;
if(n > m) swap(n, m);
}
int len = ans.size();
printf("%d\n", len);
for(int i = 0; i < len; i++) printf("%d%c", ans[i], " \n"[i == len - 1]);
}
return 0;
}