hdu1045Fire Net (一行变多行,一列变多列,最小顶点覆盖)

Fire Net

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 6280 Accepted Submission(s): 3549

Problem Description

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.

Input

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.

Output

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

PS:以前想用DFS做,但没有做出来,还是觉得二分匹配算法好用。
#include<stdio.h>
#include<string.h>
int map[50][50],vist[50],match[50],ln,rn;
int find(int i)
{
    for(int j=1;j<=ln;j++)
    if(map[i][j]&&!vist[j])
    {
        vist[j]=1;
        if(match[j]==0||find(match[j]))
        {
            match[j]=i; return 1;
        }
    }
    return 0;
}
int main()
{
    int n,mpr[5][5],mpl[5][5];
    char s;
    while(scanf("%d",&n)>0&&n)
    {
        memset(mpr,0,sizeof(mpr));
        memset(mpl,0,sizeof(mpl));
        for(int i=1;i<=n;i++)
        {
            getchar();
            for(int j=1;j<=n;j++)
            {

                scanf("%c",&s);
                if(s=='X')
                mpr[i][j]=mpl[i][j]=-1;
            }
        }
        rn=0;
        for(int i=1;i<=n;i++)//一行变多行
        for(int j=1;j<=n;j++)
        {
            while(mpr[i][j]==-1&&j<=n)j++;
            rn++;
            while(mpr[i][j]!=-1&&j<=n)
            {
                mpr[i][j]=rn; j++;
            }
        }
        ln=0;
        for(int j=1;j<=n;j++)//一列变多列
        for(int i=1;i<=n;i++)
        {
            while(mpl[i][j]==-1&&i<=n)i++;
            ln++;
            while(mpl[i][j]!=-1&&i<=n)
            {
                mpl[i][j]=ln; i++;
            }
        }
        memset(map,0,sizeof(map));
        for(int i=1;i<=n;i++)//行列建图
        for(int j=1;j<=n;j++)
        if(mpr[i][j]!=-1)
        map[mpr[i][j]][mpl[i][j]]=1;

        memset(match,0,sizeof(match));
        int ans=0;
        for(int i=1;i<=rn;i++)
        {
            memset(vist,0,sizeof(vist));
            ans+=find(i);
        }
        printf("%d\n",ans);
    }
}

hdu1045Fire Net (一行变多行,一列变多列,最小顶点覆盖)

时间: 2024-11-06 07:14:29

hdu1045Fire Net (一行变多行,一列变多列,最小顶点覆盖)的相关文章

HNU13028Attacking rooks (二分匹配,一行变多行,一列变多列)

Attacking rooks Time Limit: 20000ms, Special Time Limit:50000ms, Memory Limit:65536KB Total submit users: 12, Accepted users: 7 Problem 13028 : No special judgement Problem description Chess inspired problems are a common source of exercises in algor

一行多列变多行多列 &nbsp;

问题: aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp拆分为:aa    bb    cc    dd ee    ff    gg     hh ii      jj    kk     ll mm  nn  oo     pp 解答: xargs -n4 awk -vRS=' ' 'ORS=NR%4?" ":"\n"' sed 's/ /\n/4;P;D' 一行多列变多行多列

GreenPlum之数组合并取交集及行变列、列变行函数

--1.利用INTERSECT关键字数组之间交集函数 CREATE OR REPLACE FUNCTION array_intersect(anyarray, anyarray) RETURNS anyarray AS $$ SELECT ARRAY( SELECT UNNEST($1) INTERSECT SELECT UNNEST($2)); $$ LANGUAGE SQL; select array_intersect(array[1,2,3],array[2,3,4]); --2.行变列

[MySQL] 行列转换变化各种方法实现总结(行变列报表统计、列变行数据记录统计等)

前言: mysql行列变化,最难的就是将多个列变成多行,使用的比较多的是统计学中行变列,列变行,没有找到现成的函数或者语句,所以自己写了存储过程,使用动态sql来实现,应用业务场景,用户每个月都有使用记录数录入一张表,一个月一个字段,所以表的字段是动态增长的,现在需要实时统计当前用户使用的总数量,如果你知道有多少个字段,那么可以用select c1+c2+c3+-. From tbname where tid='111';来实现,但是关键是这个都是动态的,所以在应用程序端来实现确实不适宜,可以放

在一个每一行从左到右递增每一列从上到下递增的二维数组中查找一个整数是否存在——3

给定一个二维数组,数组的特点是:每一行从左到右数据大小依次递增,每一列数据从上到下依次递增,要求判断一个整数是否在这个二维数组中: 设计二维数组如下: 首先,毋庸置疑的的是,遍历一遍数组肯定能判断出来,这也是最笨的方法了,因此,要想提高程序的运行效率就得找出一种高效的方法来查找: 一开始的想法大概都能想到从数组第一行第一列的数开始沿着对角线判断,如果是对角线数据就可以直接返回,比如我们要想查找17这个数,这时候17比0.9.16都要大,因此以0.9.16为对角线的矩形数据就可以排除了,接下来判断

未能启用约束。一行或多行中包含违反非空、唯一或外键约束的值。

来源:http://www.cnblogs.com/JuneZhang/archive/2013/01/10/2853981.html 今天运行项目,提示“未能启用约束.一行或多行中包含违反非空.唯一或外键约束的值.”的异常信息. 在网上找了查了一些原因:http://www.cnblogs.com/muzihai1988/archive/2011/05/04/2036502.html 原因分析:强类型的DataTable和SQL语句查询出的结果不匹配. 简单说就是强类型的DataTable比S

hivepython 实现一行转多行

案例1: ==效果等同于一行转多行 数据表名称:zhangb.gid_tags 数据格式,每行是2个字段,(gid,tags) ,可能有脏数据,分隔符为"\t", ANDROID-9de77225cadb4319adfc1b1fe51c54f0        h65010000,014200,018100,011300,0200 ANDROID-9de77dfdbbab42679eed11f4e48c0ffc         022000,026400,022400,016400,01

oralce逗号分割变多行 Oracle中REGEXP SUBSTR函数

Oracle中REGEXP_SUBSTR函数 Oracle中REGEXP_SUBSTR函数的使用说明: 题目如下: 在oracle中,使用一条语句实现将'17,20,23'拆分成'17','20','23'的集合. REGEXP_SUBSTR函数格式如下: function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier) __srcstr     :需要进行正则处理的字符串 __pattern    :进行匹配的正则表

删除dataGridview中选中的一行或多行

DialogResult RSS = MessageBox.Show(this,"确定要删除选中行数据码?","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Warning); switch(RSS) { case DialogResult.Yes: for (int i = this.dataGridView1.SelectedRows.Count; i > 0; i--) { int ID = Convert.ToI