牛客多校,第七场。
若有公式图片无法正常显示,请使用梯子访问!
B - Mask Allocation
- 
    题意: 
 给定n*m个物品,要求构造出k堆物品,并使这些堆可以任意组合为n堆m个物品与m堆n个物品,求最小的k以及对应方案。样例1解释: 
 输入
 5 4
 输出
 8
 4 4 4 4 1 1 1 1
 n堆m个物品:(4),(4),(4),(4),(1+1+1+1)
 m堆n个物品:(4+1),(4+1),(4+1),(4+1)
- 
    思路: 
 贪心构造即可。迭代依次构造较小的数的平方,再依次减即可。例如: 
 输入 n=13 m=5 时:- 
        较小数=5,构造5*5: 
 ans={5,5,5,5,5}, 剩余m=8, n=5
- 
        较小数=5, 构造5*5: 
 ans={5,5,5,5,5,5,5,5,5,5}, 剩余m=3, n=5
- 
        较小数=3, 构造3*3: 
 ans={5,5,5,5,5,5,5,5,5,5,3,3,3},剩余m=3, n=2
- 
        较小数=2, 构造2*2: 
 ans={5,5,5,5,5,5,5,5,5,5,3,3,3,2,2},剩余m=1, n=2
- 
        较小数=1,构造1*1: 
 ans={5,5,5,5,5,5,5,5,5,5,3,3,3,2,2,1},剩余m=1, n=1
- 
        现在m=1,n=1,最后补一个1即可。 
 如上,即为贪心最优解思路。 
- 
        
int main()
{
    IOS;
    int T;
    cin >> T;
    while (T--)
    {
        int n, m;
        cin >> n >> m;
        if (n < m) //默认n>m
            swap(n, m);
        vector<int> ans;
        while (1)
        {
            for (int i = 0; i < m; i++) // 构造较小物品
                ans.push_back(m);
            n -= m; 
            if(n*m==0) //当没有物品可以构造
            break;
            if (n < m) //默认n>m
                swap(n, m);
        }
        cout << ans.size() << endl;
        for (int i = 0; i < ans.size(); i++)
            cout << ans[i] << " ";
        cout << endl;
    }
    return 0;
}