NEFU559 分书问题【递归】

来源:互联网 发布:淘宝卖家自建物流 编辑:程序博客网 时间:2024/05/16 14:13

题目链接:

http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=559


题目大意:

有编号分别为1~N的N本书,准备分给N个人,每个人阅读兴趣用一个二维数组表示。

1:喜欢这本书;0:不喜欢这本书。

Like[i][j] = 1,i喜欢书j;Like[i][j] = 1,i不喜欢书j。

问:如何分书才能使得所有人都满意,输出第i个人分得的书的编号,如果有多个答案

输出序列数小的那一组。


思路:

序列要求从小到大,那么就从小到大递归美剧每个人喜欢的书,找到第一组答案就可以

了。用vis[]数组来判断第i本书是否被选,ans[]数组来存储输出序列。从第一个人开始选

书,到最后一个人选完书,对于每个人,找出未被选、并且自己喜欢的书进行选择,并

用vis[]标记,将序列号存入ans[]数组。然后判断剩下的人是否满足人手一本的条件(递归

判断),如果不能则将vis[]还原(恢复现场),表示不能选择该书。


AC代码:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;int Like[130][130],vis[130],ans[130],N;int search(int M){if(M == N)return true;for(int i = 0;i < N; ++i)//判断第i本书是否备选,第M个人是否喜欢第i本书 {if(!vis[i] && Like[M][i]){vis[i] = 1; ans[M] = i+1;//第M个人选了第i本书 if(search(M+1))//剩下的能否人手配一本,可以就返回 return 1;vis[i] = 0;//不可以人手配一本,就不能选择第i本书(恢复现场) }} return 0;} int main(){while(~scanf("%d",&N)){for(int i = 0; i < N; ++i)for(int j = 0; j < N; ++j)scanf("%d",&Like[i][j]); memset(vis,0,sizeof(vis));memset(ans,0,sizeof(ans));search(0);for(int i = 0; i < N; ++i)if(i != N-1)printf("%d ",ans[i]);elseprintf("%d\n",ans[i]);} return 0;} 



0 0