6-12 世界名画陈列馆问题
问题描述
世界名画陈列馆由 个排列成矩形阵列的陈列室组成。为了防止名画被盗,需要在陈列室中设置警卫机器人哨位。每个警卫机器人除了监视它所在的陈列室外,还可以监视与 它所在的陈列室相邻的上、下、左、右 4 个陈列室。试设计一个安排警卫机器人哨位的算法, 使得名画陈列馆中每一个陈列室都在警卫机器人的监视之下,且所用的警卫机器人数最少。
设计一个优先队列式分支限界法,计算警卫机器人的最佳哨位安排,使得名画陈列馆中 每一个陈列室都在警卫机器人的监视之下,且所用的警卫机器人数最少。
数据输入:
第一行有 2 个正整数 m 和 n (1≤m,n≤20)。
Java
package Chapter6FenZhiXianJieFa;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
public class ShiJieMingHuaChenLieGuan {
private static class HeapNode implements Comparable{
int i,j,k,t;
int[][] x,y;
public int compareTo(Object o){
HeapNode heapNode = (HeapNode) o;
int result = Integer.compare(k, heapNode.k);
return result;
}
private void heapNode(int n, int m){
x = new int[n+2][m+2];
y = new int[n+2][m+2];
for(int a=0; a<=n+1; a++)
for(int b=0; b<=m+1; b++){
x[a][b]=0; y[a][b]=0;
}
for(int a=0; a<=m+1; a++) {y[0][a]=1; y[n+1][a]=1;}
for(int a=0; a<=n+1; a++) {y[a][0]=1; y[a][m+1]=1;}
i=1; j=1; k=t=0;
}
}
private static class Robot{
int[][] bestx;
int n,m,best;
boolean p;
private void compute(){
bestx = new int[n+2][m+2];
if(n==1 && m==1){System.out.println(1); System.out.println(1); return;}
pqbb();
output();
}
private void pqbb(){
Queue<HeapNode> H = new PriorityQueue<>();
HeapNode E = new HeapNode();
E.heapNode(n,m);
while (true){
int i=E.i, j=E.j, k=E.k, t=E.t;
if(t == n*m) {best=k; copy(bestx,E.x); return;}
else {
if(i < n) change(H,E,i+1,j);
if(j<m && (E.y[i][j+1]==0 || E.y[i][j+2]==0)) change(H,E,i,j+1);
if(E.y[i+1][j]==0 && E.y[i][j+1]==0) change(H,E,i,j);
}
if(H.isEmpty()) break;
E = H.poll();
}
}
private void change(Queue<HeapNode> H, HeapNode E, int i, int j){
HeapNode N = new HeapNode();
N.heapNode(n,m);
N.i=E.i; N.j=E.j; N.k=E.k+1; N.t=E.t;
for(int a=0; a<=n+1; a++)
for(int b=0; b<=m+1; b++){
N.x[a][b] = E.x[a][b];
N.y[a][b] = E.y[a][b];
}
N.x[i][j] = 1;
for(int s=1; s<=5; s++){
int p = i+d[s][1];
int q = j+d[s][2];
N.y[p][q]++;
if(N.y[p][q] == 1) N.t++;
}
while (!(N.y[N.i][N.j]==0 || N.i>n)){
N.j++;
if(N.j > m) {N.i++; N.j=1;}
}
H.add(N);
}
private void copy(int[][] x, int[][] y){
for(int i=0; i<=n; i++)
for(int j=0; j<=m; j++)
x[i][j] = y[i][j];
}
private 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();
}
}
private void init(){
Scanner input = new Scanner(System.in);
n = input.nextInt();
m = input.nextInt();
p = false;
if(n < m) {int tmp=n; n=m; m=tmp; p=true;}
}
}
private static int[][] d = {{0,0,0},{0,0,0},{0,0,-1},{0,-1,0},{0,0,1},{0,1,0}};
public static void main(String[] args){
while (true){
Robot X = new Robot();
X.init();
X.compute();
}
}
}
Input & Output
4 4
4
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
5 5
7
0 0 1 0 0
1 0 0 0 1
0 0 1 0 0
0 0 1 0 0
1 0 0 0 1
Reference
王晓东《计算机算法设计与分析》(第3版)P229