本专栏持续输出数据结构题目集,欢迎订阅。
题目
分书问题是指:已知 n 个人对 m 本书的喜好(n≤m),现要将 m 本书分给 n 个人,每个人只能分到 1 本书,每本书也最多只能分给 1 个人,并且还要求每个人都能分到自己喜欢的书。列出所有满足要求的方案。
本题请你尝试给出递归实现的解。
输入格式:
输入第一行给出两个正整数 n 和 m(n≤m),即分书问题中的人数和书的数量。由于本题仅用于测试递归算法,此处的 m 取固定值 4。
随后 n 行,每行给出 m 个关系矩阵元素。其中第 i 行第 j 个元素为 1 表示第 i 个人喜欢第 j 本书,为 0 则表示不喜欢。
输出格式:
按升序列出所有满足要求的方案,格式为 (s1,⋯,sn)。其中 s
i 表示第 i 个人分到了第 si 本书。
注:方案 (a1,⋯,an)<(b1,⋯,bn) 是指存在 1≤k≤n,使得 ai=bi 对所有 1≤i<k 成立,并且有 ak <bk。
输入样例:
3 4
0 1 0 1
1 0 1 0
1 1 0 0
输出样例:
(2, 3, 1)
(4, 1, 2)
(4, 3, 1)
(4, 3, 2)
代码
#include <stdio.h>
#include <stdbool.h>
int n, m; // 人数和书数
int preference[10][10]; // 喜好矩阵 (1-based索引)
int solution[10]; // 存储当前方案
bool used[10]; // 标记书是否已被分配
// 递归函数:为第person个人分配书
void assign_books(int person) {
// 递归终止条件:所有的人都已分配到书
if (person > n) {
// 输出当前方案
printf("(");
for (int i = 1; i <= n; i++) {
printf("%d", solution[i]);
if (i < n) {
printf(", ");
}
}
printf(")\n");
return;
}
// 尝试为当前人分配每一本书
for (int book = 1; book <= m; book++) {
// 检查条件:书未被分配,且当前人喜欢这本书
if (!used[book] && preference[person][book] == 1) {
// 分配这本书
used[book] = true;
solution[person] = book;
// 递归为下一个人分配书
assign_books(person + 1);
// 回溯:撤销分配,尝试其他可能
used[book] = false;
}
}
}
int main() {
scanf("%d %d", &n, &m);
// 读取喜好矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &preference[i][j]);
}
}
// 初始化:所有书都未被分配
for (int i = 1; i <= m; i++) {
used[i] = false;
}
// 从第1个人开始分配
assign_books(1);
return 0;
}
732

被折叠的 条评论
为什么被折叠?



