3556 - 【搜索与回溯】选书(例题)
时间限制 : 1 秒
内存限制 : 128 MB
【例7】选书
学校放寒假时,信息学竞赛辅导老师有A,B,C,D,E五本书,要分给参加培训的张、王、刘、孙、李五位同学,每人只能选一本书。老师事先让每个人将自己喜欢的书填写在如下的表格中。然后根据他们填写的表来分配书本,希望设计一个程序帮助老师求出所有可能的分配方案,使每个学生都满意。

题目输入
无输入。
题目输出
输出所有选书方案,每种方案六行;
每一行输出方案数,格式:answer XX:(XX为方案数)
接下来五行输出五位学生所选的书,五位学生姓名用"Student Zhang, Student Wang, Student Liu, Student Sun, Student Li"表示,参考样例输出。
输入/输出样例
输入格式
no input needed
输出格式
answer 1: Student Zhang:C Student Wang:A Student Liu:B Student Sun:D Student Li:E
C++解答
#include<cstdio> #include<iostream> #include<cstdlib> using namespace std; int book[6],c; bool flag[6],like[6][6]={{0,0,0,0,0,0},{0,0,0,1,1,0},{0,1,1,0,0,1}, {0,0,1,1,0,0},{0,0,0,0,1,0},{0,0,1,0,0,1}};; char s[5][20]={"Student Zhang","Student Wang","Student Liu","Student Sun","Student Li"}; int search(int); int print(); int main() { for (int i=1;i<=5;i=i+1) flag[i]=1; search(1); //从第1个开始选书,递归。 return 0; } int search(int i) //递归函数 { for (int j=1;j<=5; j++) //每个人都有5本书可选 if (flag[j]&&like[i][j]) //满足分书的条件 { flag[j]=0; //把被选中的书放入集合flag中,避免重复被选 book[i]=j; //保存第i个人选中的第j本书 if (i==5) print(); //i=5时,所有的人都分到书,输出结果 else search(i+1); //i<5时,继续递归分书 flag[j]=1; //回溯:把选中的书放回,产生其他分书的方案 book[i]=0; } return 0; } int print() { c=c+1; //方案数累加1 cout <<"answer " <<c <<":\n"; for (int i=1;i<=5;i=i+1) cout <<s[i-1]<<":" <<char(64+book[i]) <<endl; //输出分书的方案 return 0; }