回溯法2——和尚挑水
题目: 和尚挑水
某寺庙里7个和尚:轮流挑水,为了和其他任务不能冲突,各人将有空天数列出如下表:
和尚1: 星期二,四;
和尚2: 星期一,六;
和尚3: 星期三,日;
和尚4: 星期五;
和尚5: 星期一,四,六;
和尚6: 星期二,五;
和尚7: 星期三,六,日;
请将所有合理的挑水时间安排表。
思路:使用回溯法,进行试错,较八皇后问题更简单点,因为每个和尚只需判断自己没有其他和尚与自己选择同一天,即只需判断其上方是否冲突。
代码和八皇后基本一致。
#include<iostream> using namespace std; const int SETED=100; // 每行代表一个和尚 // ready[i][j]=1表示第i个和尚第j天有空。 int ready[7][7]={ 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1 }; int res[7][7]={0}; void show_result(){ static int count=1; printf("第%d种分配方案:\n",count); ++count; for(int i=0;i<7;++i){ for(int j=0;j<7;++j){ if(ready[i][j]>10){ cout<<"1 "; }else{ cout<<0<<" "; } } cout<<endl; } cout<<endl<<endl; } //冲突检测函数,每个和尚只需要判断其选择的日期内没有其他和尚就行。 //即位置上方没有冲突 int conflict(int row, int column){ for(int i=1;i<7;++i){ //上 if(row-i>=0 &&ready[row-i][column]>10) return 1; } return 0; } void result(int row){ for(int column=0;column<7;++column){ if( 1!=ready[row][column] ) continue; ready[row][column]+=SETED; if(!conflict(row,column)){ if(row<6) result(row+1); else show_result(); } ready[row][column]-=SETED;//回溯的本意 } } int main(){ result(0); return 0; }