和尚挑水问题

有7个和尚,一星期七天每天安排一个和尚挑水,每个和尚在每周中空闲的时间不一。用一个二维数组M[][]来表示7个和尚在7天中是否可以挑水,M[i][j]==1表示第i个和尚在第j天可以挑水,M[i][j]==0表示第i个和尚在第j天不可以挑水。现输入矩阵M,要求求出方案的总数,并逐天输出挑水的和尚。

 

可以考虑用回溯法解决该问题,第i天选取符合条件的和尚j挑水,则和尚j不能在其他的天里挑水,设置visited[j]=1,第i+1天若存在可挑水的和尚,则选取,若不存在,则返回第i天,选取非j和尚挑水。可以利用递归来实现回溯。

 

import java.util.*;
public class Arrange {	
	static int M[][] = new int[8][8];
	static int sum = 0;
	static ArrayList<Integer> allArranges = new ArrayList<>();//用来存储所有安排方案
	static Integer arrange[] = new Integer[8];//存储当前单个安排方案 
	static int visited[] = new int[8];//visited[i]的值描述地i个和尚是否被访问过,1表示已被访问,0表示未被访问;
	
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
	    for(int i=1;i<8;i++){
	        for(int j=1;j<8;j++){
	            M[i][j] = in.nextInt();
	        }
	    }
	    in.close();
	    //初始化
	    for(int i=1;i<8;i++){
	        arrange[i]=0;
	        visited[i]=0;
	    }
	    backTrack(1);
	    //输出方案
	    System.out.print(sum+"\n");	    
	    for(int i=0; i<sum; i++){	    	
	    	for(int j=0; j<7; j++){
	    		System.out.print(allArranges.get(i*7+j)+" ");
	    	}
	    	System.out.println();
	    }
	}
	
	static void backTrack(int t){//用递归来实现回溯,t代表第t天
	    if(t==8){
	    	for(int i=1; i<8; i++){
	    		allArranges.add(arrange[i]);
	    	}
	        sum++;
	    }
	    else{
	        for(int i=1;i<8;i++){
	            if(visited[i]==0 && M[i][t]==1){
	            	arrange[t]=i;
	                visited[i]=1;
	                backTrack(t+1);
	                visited[i]=0;
	            }
	        }
	    }
	}
	
}


示例:

 

输入:

1 0 0 1 0 1 0
0 0 1 1 0 0 0
0 1 0 0 1 0 1
1 1 0 0 0 1 0
0 0 1 0 1 0 0
0 0 0 1 0 0 1
1 0 0 0 1 0 0

输出

5
1 3 5 2 7 4 6 
4 3 5 2 7 1 6 
7 3 2 1 5 4 6 
7 4 2 6 5 1 3 
7 4 5 2 3 1 6 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值