0
点赞
收藏
分享

微信扫一扫

NEFU559 分书问题【递归】

金穗_ec4b 2022-07-27 阅读 48


题目链接:

​​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]);
else
printf("%d\n",ans[i]);
}

return 0;
}




举报

相关推荐

0 条评论