传送门
题意:已知n,m,有n*m个物资,要求输出一个序列,具体一个数不能拆开,但多个数可以组合在一起,要求该序列可以平均组合成n组或m组,且必须字典序最大
我想了半天,一直想着找规律把序列给凑出来,中间我好像也想到过递归,但停留时间太短,没有拿递归,谁知道递归这么简单,555菜哭了人,果然我还是差点火候,然后超级棒的队友貌似找到了规律,ac了,接下来是我补题时用的递归思考过程
n*m个物资需要都能组合成n组或m组(让n始终>m),我们就可以先拎出m个m,然后剩下的left就可以转化成一个子问题(n-m,m),然后就可以写递归了,有个注意点强调一下,就是递归的结束终点,n==m输出n个m,还有就是出现1那就输出若干个1
AC代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
int t;
int n,m;
int ans[1000005];
int cnt = 0;
void f(int n, int m)
{
if (n < m) swap(n, m);
if (m == 1)
{
for (int i = 1; i <= n; i++)
{
ans[cnt++] = 1;
}
return;
}
if (n == m)
{
for (int i = 1; i <= n; i++)
{
ans[cnt++] = m;
}
}
else if (n > m)
{
for (int i = 1; i <= m; i++)
{
ans[cnt++] = m;
}
int left = n * m - m * m;
f(n - m, m);
}
}
int main()
{
cin >> t;
while (t--)
{
memset(ans, 0, sizeof(ans));
cnt = 0;
cin >> n >> m;
f(n, m);
sort(ans, ans + cnt);
cout << cnt << endl;
for (int i = cnt - 1; i >= 0; i--)
{
cout << ans[i] << " ";
}
cout << endl;
}
}