您的位置:首页 > 编程语言 > Java开发

【华为机试题】和尚挑水

2016-04-15 18:56 465 查看
有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 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息