標籤:
題目連結:
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;}
NEFU559 分書問題【遞迴】