世界名画陈列馆由 m×n m × n 个排列成矩形阵列的陈列室组成。为了防止名画被盗,需要在陈列室中设置警卫机器人哨位。每个警卫机器人除了监视它所在的陈列室外,还可以监视与 它所在的陈列室相邻的上、下、左、右 4 个陈列室。试设计一个安排警卫机器人哨位的算法, 使得名画陈列馆中每一个陈列室都在警卫机器人的监视之下,且所用的警卫机器人数最少。
设计一个算法,计算警卫机器人的最佳哨位安排,使得名画陈列馆中每一个陈列室都在 警卫机器人的监视之下,且所用的警卫机器人数最少。
数据输入:
第一行有 2 个正整数 m 和 n (1≤m,n≤20)。
package Chapter5HuiSuFa;
import java.util.Arrays;
import java.util.Scanner;
public class ShiJieMingHuaChenLieGuan {
private static int MAX = 1000000;
private static int MLEN = 50;
private static int m,n;
private static int[][] d = {{0,0,0},{0,0,0},{0,0,-1},{0,-1,0},{0,0,1},{0,1,0}};
private static int[][] x,y,bestx;
private static int best,k,t,t1,t2,more;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
k = 0;
t = 0;
n = input.nextInt();
m = input.nextInt();
x = new int[MLEN+1][MLEN+1];
y = new int[MLEN+1][MLEN+1];
bestx = new int[MLEN+1][MLEN+1];
compute();
}
}
private static void compute(){
more = m/4+1;
if(m%4 == 3) more++;
else if(m%4 == 2) more+=2;
t2 = m*n+more+4;
t1 = m*n+4;
best = MAX;
if((n==1) && (m==1)){
System.out.println(1);
System.out.println(1);
return;
}
for(int i=0; i<=m+1; i++){
y[0][i] = 1;
y[n+1][i] = 1;
}
for(int i=0; i<=m+1; i++){
y[i][0] = 1;
y[i][m+1] = 1;
}
search(1,0);
output();
}
private static void search(int i, int j){
do{
j++;
if(j > m) { i++; j=1; }
}while (!((y[i][j]==0) || (i>n)));
if(i > n){
if(k < best) { best=k; copy(bestx,x); }
return;
}
if(k+(t1-t)/5 >= best) return;
if((i1) && (k+(t2-t)/5)>=best) return;
if(i < n){
change(i+1,j);
search(i,j);
restore(i+1,j);
}
if((j1]==0) || (y[i][j+2]==0))){
change(i,j+1);
search(i,j);
restore(i,j+1);
}
if((y[i+1][j]==0) && (y[i][j+1]==0)){
change(i,j);
search(i,j);
restore(i,j);
}
}
private static void change(int i, int j){
x[i][j] = 1; k++;
for(int s=1; s<=5; s++){
int p = i+d[s][1];
int q = j+d[s][2];
y[p][q]++;
if(y[p][q]==1) t++;
}
}
private static void restore(int i, int j){
x[i][j] = 0; k--;
for(int s=1; s<=5; s++){
int p = i+d[s][1];
int q = j+d[s][2];
y[p][q]--;
if(y[p][q]==0) t--;
}
}
private static void copy(int[][] des, int[][] src){
for(int i=0; iprivate static void output(){
System.out.println(best);
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++)
System.out.print(bestx[i][j]+" ");
System.out.println();
}
}
}
4 4
4
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
8 13
26
0 0 0 0 1 0 0 0 1 0 0 1 0
1 1 1 0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 1 1 0 1
0 0 1 0 0 0 0 1 0 0 0 0 0
1 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 1 1 0 0 0
0 1 0 0 0 0 1 0 0 0 0 0 1
0 1 0 0 1 0 0 0 1 0 1 0 0
王晓东《计算机算法设计与分析》(第3版)P186