内卷之源:
暂无
题目描述:
* 圣诞节到了,城堡里有k个小朋友,圣诞老人魔法口袋里带了n件无差别的小礼物。
* 请帮圣诞老人处理:将n个无差别的礼物分给k个小朋友的分法问题。
*
* 输入描述:
* 仅一行,包含2个整数 n(0<=n<=10) 和 k(1<=k<=10),n表示礼物的数量,k表示小朋友的数量
* 输出描述:
* 第一行输出分法总数t
* 后续t行依次列出每种分法:每件礼物用字符‘*’(ascii码为42)表示,用字符‘|’(ascii码为124)分隔小朋友。具体输出和顺序请参考示例。
测试用例:
* 示例一:
* 输入 3 2
* 输出 4
* ***| //给第一个小朋友分3件,给第二个小朋友分0件
* **|* //给第一个小朋友分2件,给第二个小朋友分1件
* *|** //给第一个小朋友分1件,给第二个小朋友分2件
* |*** //给第一个小朋友分0件,给第二个小朋友分3件
* 示例二:
* 输入 4 3
* 输出 15
* ****|| //给第一个小朋友分4件,给第二个小朋友分0件,给第三个小朋友分0件
* ***|*| //给第一个小朋友分3件,给第二个小朋友分1件,给第三个小朋友分0件
* ***||* //给第一个小朋友分3件,给第二个小朋友分0件,给第三个小朋友分1件
* **|**| //给第一个小朋友分2件,给第二个小朋友分2件,给第三个小朋友分0件
* **|*|* //给第一个小朋友分2件,给第二个小朋友分1件,给第三个小朋友分1件
* **||** //给第一个小朋友分2件,给第二个小朋友分0件,给第三个小朋友分2件
* *|***| //给第一个小朋友分1件,给第二个小朋友分3件,给第三个小朋友分0件
* *|**|* //给第一个小朋友分1件,给第二个小朋友分2件,给第三个小朋友分1件
* *|*|** //给第一个小朋友分1件,给第二个小朋友分1件,给第三个小朋友分2件
* *||*** //给第一个小朋友分1件,给第二个小朋友分0件,给第三个小朋友分3件
* |****| //给第一个小朋友分0件,给第二个小朋友分4件,给第三个小朋友分0件
* |***|* //给第一个小朋友分0件,给第二个小朋友分3件,给第三个小朋友分1件
* |**|** //给第一个小朋友分0件,给第二个小朋友分2件,给第三个小朋友分2件
* |*|*** //给第一个小朋友分0件,给第二个小朋友分1件,给第三个小朋友分3件
* ||**** //给第一个小朋友分0件,给第二个小朋友分0件,给第三个小朋友分4件
思路分析:
* 根据输出格式可知,第一个小朋友的礼物数量按总数递减。第(k-1)个小朋友的礼物数量每次是基于分给第(k-2)个小朋友剩余的数量递减(显然需使用dfs)。前面所有小朋友分完后剩余的全分给最后一个小朋友。
* 另可以归纳出的是:
(1)以字符串输出具体分法,字符串长度固定是(n+k-1),其中字符‘*’的个数为(n),字符‘|’的个数为(k-1)。
(2)输入的n可为0,k可为1,此时分法均只有一种。(该情形一般dfs应该涵盖进去)
编程实现(C++):
/*
************************************************************
* @author SLF
* @version V1.0.0
* @date xx-xx-2020
************************************************************
*/
#include <iostream>
#include <string>
#include <vector>
using namespace::std;
void dfs(vector<string> &out, string method, const int &LEN, const int &n, const int &k, const int &index);
int main(void)
{
int n, k;
cin >> n >> k;
// if (0 == n)
// {//礼物数量为0
// cout << 1 << endl;
// for (int i = k-1; 0 < i; ++i)
// {//当k=1时是否该输出字符'|' ?
// cout << '|';
// }
// cout << endl;
// return 0;
// }
// if (1 == k)
// {//人数为1
// cout << 1 << endl;
// for (; 0 < n; --n)
// {
// cout << '*';
// }
// cout << endl;
// return 0;
// }
const int LEN = n + k -1;
vector<string> out;
dfs(out, "", LEN, n, k-1, 0);
cout << out.size() << endl;
for (const auto &str : out)
{
cout << str << endl;
}
return 0;
}
//第二个形参不能使用引用
void dfs(vector<string> &out, string method, const int &LEN, const int &n, const int &k, const int &index)
{
if (LEN == index)
{
out.push_back(method);
return;
}
if (0 < n)
{
dfs(out, method + '*', LEN, n -1, k, index +1); // method + '*' 并不会改变本层的method字符串,只会改变下一层
}
if (0 < k)
{
dfs(out, method + '|', LEN, n, k -1, index +1); // method + '|' 并不会改变本层的method字符串,只会改变下一层
}
}
郑重提示:①解题思路非最优,覆盖条件可能不全,仅供练习参考。
②若有更佳思路或疑问,可在评论区留言相互讨论,不亦乐乎。
③本文不允许转载,若认可本文,可点赞收藏关注。