ZOJ(ZJU) 1002 Fire Net(深搜)

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.

A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.

Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.

The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.

Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.

The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a ‘.’ indicating an open space and an uppercase ‘X’ indicating a wall. There are no spaces in the input file.

For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.

Sample input:

4
.X..
….
XX..
….
2
XX
.X
3
.X.
X.X
.X.
3

.XX
.XX
4
….
….
….
….
0

Sample output:

5
1
5
2
4

题目大意:
假设我们有一个正方形的城市,其街道都是直的。在方形的地图上,有n行和n列,每个代表一条街道或一堵墙。每个碉堡有4个射击孔,分别正对东西南北方向。在每个射击孔配置一架高射机枪。
我们假设,子弹是如此强大,它的射程可以任意远,并能摧毁它射中的碉堡。另外,墙也是很坚固的,可以挡住子弹!
其目标是,在该城市布置尽可能多的碉堡,而碉堡之间又不好互相摧毁。合理布置碉堡的原则是:没有两个碉堡在一个水平方向或垂直方向,除非它们之间有墙相隔!
在本题中,假设城市很小,(n最大为4) ,而且子弹不能贯穿墙壁。

输入n,代表n行n列。
n为0是输入结束。
‘.’代表空地,’X’代表墙壁。

因为题目规模很小,直接采用深度优先算法就可以解决。

import java.util.Scanner;

public class Main{

    static int n;
    static int time;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            n =sc.nextInt();
            if(n==0){
                return ;
            }
            char[][] map = new char[n][n];
            for(int i=0;i<n;i++){
                String str = sc.next();
                for(int j=0;j<n;j++){
                    map[i][j] = str.charAt(j);
                    //System.out.print("a"+map[i][j]);
                }
                //System.out.println();
            }
            time=0;
            dp(map,0,0);
            System.out.println(time);
        }

    }

    /**
     * 利用深搜的方法,对每个单元格能否放置碉堡进行判断
     * @param map
     * @param k
     * @param count
     */
    private static void dp(char[][] map, int k, int count) {
        int x,y;
        if(k==n*n){//整个地图判断完毕
            if(count>time){//是否有更大的值
                time=count;
                return ;
            }
        }else{
            //将单元数转换为xy坐标
            x =k/n;
            y =k%n;

            //如果本单元格可以放置碉堡
            if(map[x][y]=='.'&&CanPut(map,x,y)){
                map[x][y]='O';//放置下一个碉堡
                //令count加一,并递归到下一个单元格
                dp(map,k+1,count+1);
                //递归完毕,恢复该单元格
                map[x][y]='.';
            }
            //本单元格不能放置碉堡
            dp(map,k+1,count);
        }
    }

    /**
     * 判断行x和列y处能不能配置碉堡
     * @param map
     * @param x
     * @param y
     * @return
     */
    private static boolean CanPut(char[][] map,int x, int y) {
        for(int i=x-1;i>=0;i--){//判断y列上的合法性
            if(map[i][y]=='O') return false;
            if(map[i][y]=='X') break;
        }

        for(int i=y-1;i>=0;i--){//判断x行上的合法性
            if(map[x][i]=='O') return false;
            if(map[x][i]=='X') break;
        }
        return true;
    }

}
时间: 2024-07-29 01:14:32

ZOJ(ZJU) 1002 Fire Net(深搜)的相关文章

ZOJ 1002 - Fire Net 的答案(回溯法)

       ---------------------------------------------------------------------------------------------------------------------------        严格来讲,此题并不算我做出来的.因为我在WA后忍不住搜索了这道题的网上资料,并在参考了"洞庭散人"的代码后AC的.          ----------------------------------------

acm-邻接矩阵能进行深搜么。现在会邻接表的深搜,还用把邻接矩阵转化为邻接表吗

问题描述 邻接矩阵能进行深搜么.现在会邻接表的深搜,还用把邻接矩阵转化为邻接表吗 邻接矩阵如果能进行的话.麻烦大神给点代码啊.小白..如题...... 解决方案 void dfs(int i){ visited[i]=1; for(int j=0;j<n;j++){ if(G[i][j]==1&&visited[j]==0){ dfs(j); } } } 解决方案二: 这是用邻接矩阵求最小生成树的,题主看下能否帮的上忙,如果能帮的上,希望可以采纳 #include #include

c++-UVa1374快速幂运算迭代深搜法 ,C++初学者,求优化方法

问题描述 UVa1374快速幂运算迭代深搜法 ,C++初学者,求优化方法 这是我的代码,优化过几次,但是还是很慢很慢,求大神给优化途经,就是在我的代码的进行优化 #include #include #include #include using namespace std; bool search(int,set&,int dep,int); int MAX=1; int tempMax; int main() { sets;int n; for(n=2;n!=1000;++n) { s.cle

穷举搜索:回溯与深搜

计算机常用算法大致有两大类,一类叫蛮力算法,一类叫贪心算法,前者常使用的手段就是搜索,对全部解空间进行地毯式搜索,直到找到指定解或最优解. [建立解空间] 问题的解应该如何描述,如何建立?借助图论的思想,我们可以用图来描述,图的定义为G,由顶点集和边集构成,顶点即实实在在的数 据.对象,而边可以抽象为关系,即顶点间的关系,这种关系不一定非要在数据结构上表现出来,用数据结构的语言来描述,如果关系是一对一,则为线性表,如果 关系是一对多,则为树,如果关系是多对多,则为图,如果完全没有关系,则为集合.

HDOJ/HDU 1242 Rescue(经典BFS深搜-优先队列)

Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison. Angel's friends want to save Angel. Their task is: approa

HDOJ/HDU 1015 Safecracker(深搜)

Problem Description === Op tech briefing, 2002/11/02 06:42 CST === "The item is locked in a Klein safe behind a painting in the second-floor library. Klein safes are extremely rare; most of them, along with Klein and his factory, were destroyed in Wo

深搜算法实例:老鼠走迷宫(一)

这个是简单的深搜,应该输入深搜中抛砖型的,联系下代码,回顾一下深搜的思想. 本题的要求是,在开始点(1,1)和终点(5,5)放一只老鼠,让老鼠找到一条路径走出去(暂时不考虑最短路径),找到后输出路径. 最简单的想法就是对于上下左右四个进行刨根型的搜索,找到就返回输出,进入死胡同了就原路返回,找最近的有其他路径的点,继续搜索,知道找出为止. 下面是代码部分. #include <stdio.h> #include <stdlib.h> #define SUCCESS 1 #defin

深搜算法:倒油/面向对象的思想来做

题目:有一位厨师要从盛12斤油(a桶)的桶中倒出6斤油来,可是手边只有盛8斤油(b桶)和盛5斤油(c桶)的两个桶,问如何操作才能将6斤取出来呢? 下面为JAVA实现代码: 主类: package cn.hncu.oil.dfs1; import cn.hncu.oil.common.Bucket; import cn.hncu.oil.common.DumpCase; import cn.hncu.oil.common.Myset; public class DumpOilDFS { publi

HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)

Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried despe