Fire Net

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 10   Accepted Submission(s) : 3

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

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

题意:

给出你正方形的边长格数(n<=4),并在随机在某些位置放上墙,除了由墙隔开的,一个十字架方向上不能重,问你最多能放多少架大炮。
分析:
计算出每个空位的十字架方向上有多少个空位,即:将会有多少会与其冲突。然后排序选择十字架方向上空位最少的位置,(最少的位置干扰最少,最有可能架大炮)开始判断是否能够放大炮。
因此,该函数包括两个最重要的函数:count(计数),bool right(判断是否正确)
  计数时:要判断四个方向,遇墙break。
  bool right:也要判断四个方向,遇墙break,如果遇到map[][]=1,说明该图此位置已有大炮,返回false,否则检测到最后都行返回true。如果该位置可以的话要将map中的数置为1,作为标记。
代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;/*
int cmp(const void *a,const void *b){
        return *(int*)a-*(int*)b;
}*/
int count(int a[4][4],int row,int col,int n){/*数数,计算每个空位,十字架方向上所有能够放的,即会发生冲突的数目*/
    int count1=0,i;/*注意四个方向,count计数,别忘了设初值为0*/
    for(i=row-1;i>=0;i--){/*up*/
        if(a[i][col]==2)/*碰到墙才会停止*/
            break;
        else
            count1++;
    }
    for(i=row+1;i<n;i++){/*down*/
        if(a[i][col]==2)
            break;
        else
            count1++;
    }
    for(i=col-1;i>=0;i--){/*left*/
        if(a[row][i]==2)
            break;
        else
            count1++;
    }
    for(i=col+1;i<n;i++){/*right*/
        if(a[row][i]==2)
            break;
        else
            count1++;
    }
    return count1;
}
bool right(int a[4][4],int row,int col,int n){/*判断是否可以安置炮*/
    int i;
        for(i=row-1;i>=0;i--){/*用bool型*/
        if(a[i][col]==1)/*十字架方向上碰到架炮的地方,就说明有冲突,即此处不可行*/
            return false;
        else if(a[i][col]==2)/*碰到墙停止*/
            break;
    }
    //down
    for(i=row+1;i<n;i++){/*仍旧是四个方向上检测*/
        if(a[i][col]==1)
            return false;
        else if(a[i][col]==2)
            break;
    }
    //left
    for(i=col-1;i>=0;i--){
        if(a[row][i]==2)
            break;
        else if(a[row][i]==1)
            return false;
    }
    //right
    for(i=col+1;i<n;i++){
        if(a[row][i]==2)
            break;
        else if(a[row][i]==1)
            return false;
    }
    return true;
}
int main(){
    int n,i,j,k,ans;
    char c;
    int map[4][4];
    int cnt[4][4];
    while(scanf("%d",&n),n){
        k=0,ans=0;
        memset(cnt,-1,sizeof(cnt));
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
               // scanf("%c",&c);
                cin>>c;
            if(c=='.'){/*将字符型的图转化成数组型的*/
                k++;/*顺表记录下总共有多少个空的位置,方便最后检测成不成功时的循环次数*/
                map[i][j]=0;/*0表示可放的位置*/
            }
            else if(c=='X')/*X表示墙的位置*/
                map[i][j]=2;
            }
        }
        for(i=0;i<n;i++){/*计数,遇墙跳过,遇空地计数,并将地址与数目用二维数组cnt[i][j]保留下来*/
            for(j=0;j<n;j++){
                if(map[i][j]==2)
                    continue;
                else
                    cnt[i][j]=count(map,i,j,n);
            }
        }
        /*qsort(cnt,n*n,sizeof(cnt[0][0]),cmp);//!!!不能使用qsort直接对cnt排序,否则将会把位置给弄丢,所以应该使用冒泡排序*/
         int min=7,mini,minj;/*最多只能是6,用题中的最大可能做最小箱的箱底*/
         while(k--){/*有k个空位,即有k种可能性,每个位置都要判断下*/
            for(i=0;i<n;i++){
                for(j=0;j<n;j++){
                    if(cnt[i][j]==-1)
                        continue;
                    else if(cnt[i][j]<min){/*要先排排序,从最小的开始,使用贪心,因为周围的可能最少,该位成功的可能性最大*/
                        min=cnt[i][j];/*重置最小*/
                        mini=i;/*记录位置*/
                        minj=j;
                    }
                }
            }
            if(right(map,mini,minj,n)){/*判断是否能够放*/
                map[mini][minj]=1;/*可以的话,就将map中的该位置为1,标志为有炮,便于剩下位置的判断*/
                ans++;/*成立计数加1*/
            }
            cnt[mini][minj]=-1;/*该位置不用再检测了,在cnt数组中标记下-1,直接跳过,检测第二个最小的位置*/
            min=7;/*重置最小*/

}
        /*“。”点表示可放东西,总计有多少个空,k个*/
/*            for(i=0;i<n;i++){
                for(j=0;j<n;j++){
                    if(cnt[i][j]==-1)
                        continue;
                        else if(right(map,i,j,n)){
                            map[i][j]=1;
                            ans++;
                        }

}
            }*/
        printf("%d\n",ans);/*输出*/
    }

return 0;
}

Fire Net的更多相关文章

  1. 关于SequeezeNet中的Fire Module

    在论文<SQUEEZENET: ALEXNET-LEVEL ACCURACY WITH 50X FEWER PARAMETERS AND <0.5MB MODEL SIZE>中,作者 ...

  2. FZU 2150 Fire Game

    Fire Game Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit St ...

  3. Fire

    Fire 分析: 首先,明确题意:b1,b2,--,bn 交换为b2,--,bn,b1,但这并不是意味着只能从b1开始交换,(这点从样例中可以看出),并且也不意味着交换的必须是连续的一串,可以是几个单 ...

  4. Android 轻量级输入校验库:Fire Eye

    Fire Eye是一款轻量级简单易用的Android校验库. FireEye 2.0 在 1.0 的基础上,全部重写了代码,并优化了架构,性能上和逻辑上都大大提升.只需要几行代码,即可验证用户输入,并 ...

  5. ACM: FZU 2150 Fire Game - DFS+BFS+枝剪 或者 纯BFS+枝剪

    FZU 2150 Fire Game Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  6. UVA 11624 Fire!(广度优先搜索)

    题目大意:在一个N*M的迷宫内,J代表某人(只有一个),F代表火(可能不只一个),#代表墙,火每分钟会向四周除了墙以外的地方扩散一层,问人能否在没被火烧到 之前逃出迷宫,若能逃出输出最短时间.很明显的 ...

  7. Amazon的Fire Phone之于Android开发者

    在上周Amazon也耐不住加入了手机竞争行列之中,发布了自己的Fire Phone,于是Android家族又多了一位变种成员,Android系统的碎片化程度也进一步加剧.因为工作的关系,我有幸在上个月 ...

  8. Fire!(BFS)

    Fire! Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Descr ...

  9. FZU Problem 2150 Fire Game

    Problem 2150 Fire Game Accept: 145    Submit: 542 Time Limit: 1000 mSec    Memory Limit : 32768 KB P ...

  10. hdu 1045:Fire Net(DFS经典题)

    Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

随机推荐

  1. Yale CAS + .net Client 实现 SSO 的完整版

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  2. -join 和 -split 用法

    具体可参考 PowerShell_ISE的帮助文件: -Join(一元联接运算符): 一元联接运算符 (-join <string[]>) 的优先级高于逗号.因此,如果向一元联接运算符提交 ...

  3. 应用之星推出“图文app”制作工具,并附上教程

    应用之星已推出的"图文"app制作工具,是高速制作图文电子书,图文杂志等一切有关图文资料的app生成工具,以下跟大家介绍"图文"制作教程,简单快捷,大致分三大步 ...

  4. C++在使用Qt中SLOT宏须要注意的一个小细节

    大家都知道C++虚函数的机制,对于基类定义为虚函数的地方,子类假设覆写,在基类指针或者引用来指向子类的时候会实现动态绑定. 但假设指针去调用非虚函数,这个时候会调用C++的静态绑定,去推断当前的指针是 ...

  5. android EditText输入变化事件详解

    editText.addTextChangedListener(new TextWatcher(){ public void afterTextChanged(Editable s) {    // ...

  6. C#_delegate - 用委托实现事件,Display和Log类都使用Clock对象

    //public event SecondChangeHandler OnSecondChange; 若将委托加上event,则视作是事件,不是委托,外围就不能直接对OnSecondChange传值 ...

  7. 介绍一些实用的IOS手势识别库 (COCOS2D)

    http://www.supersuraccoon-cocos2d.com/zh/2012/11/14/introduction-to-some-great-ios-gesture-recogniti ...

  8. 【转】 使用Beaglebone Black的PRU(三)——实现高达100MHz的GPIO输出

    友情提示:请先按照本系列(一)(二)的说明安装PRU工具并跑通hello world再继续按本文操作. PRU操作GPIO有很多种方式,本系列之(二)中的是一种,但最快速的方式是通过直接“写”r30和 ...

  9. python--判断数据类型可不可变

    内存是一块空间,可以比喻成一个比较大的房子,定义一个变量就是在大房子中建立一个小房子,判断一个数据类型可不可变,就是看在这个这个大房子中有没有新建小房子,可以通过id来判断,如果id没有变化则是不可变 ...

  10. Bootstrap的Affix与ScrollSpy用法 bootstrap-scrollspy && bootstrap-dropdown

    bootstrap-scrollspy && bootstrap-dropdown Bootstrap的Affix与ScrollSpy用法 http://9iphp.com/web/j ...