算法设计与分析: 6-12 世界名画陈列馆问题

6-12 世界名画陈列馆问题


问题描述

世界名画陈列馆由 m × n 个排列成矩形阵列的陈列室组成。为了防止名画被盗,需要在陈列室中设置警卫机器人哨位。每个警卫机器人除了监视它所在的陈列室外,还可以监视与 它所在的陈列室相邻的上、下、左、右 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

猜你喜欢

转载自blog.csdn.net/IOIO_/article/details/81180882