海战(洛谷 P1331)

题目描述

在峰会期间,武装部队得处于高度戒备。警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机。此外,巡洋船只和舰队将被派去保护海岸线。不幸的是因为种种原因,国防海军部仅有很少的几位军官能指挥大型海战。因此,他们考虑培养一些新的海军指挥官,他们选择了“海战”游戏来帮助学习。

在这个著名的游戏中,在一个方形的盘上放置了固定数量和形状的船只,每只船却不能碰到其它的船。在这个题中,我们仅考虑船是方形的,所有的船只都是由图形组成的方形。编写程序求出该棋盘上放置的船只的总数。

输入输出格式

输入格式:

输入文件头一行由用空格隔开的两个整数R和C组成,1<=R,C<=1000,这两个数分别表示游戏棋盘的行数和列数。接下来的R行每行包含C个字符,每个字符可以为“#”,也可为“.”,“#”表示船只的一部分,“.”表示水。

输出格式:

为每一个段落输出一行解。如果船的位置放得正确(即棋盘上只存在相互之间不能接触的方形,如果两个“#”号上下相邻或左右相邻却分属两艘不同的船只,则称这两艘船相互接触了)。就输出一段话“There are S ships.”,S表示船只的数量。否则输出“Bad placement.”。

输入输出样例

输入样例#1:

6 8
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#

输出样例#1:

There are 5 ships.
/*
  一道搜索题,加上一点判断,判断所找到的连通块是不是长方形
判断的方法:假设是长方形,找到四个顶点,算连通块的面积是不是等于点的个数
*/
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define M 1010
using namespace std;
bool vis[M][M];
int map[M][M],qx[M*M],qy[M*M],n,m,cnt;
int ax[4]={0,0,1,-1};
int ay[4]={1,-1,0,0};
struct node
{
    int x,y;
};node ship[M*M];
int read()
{
    char c=getchar();int num=0,flag=1;
    while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return num*flag;
}
void bfs(int a,int b)
{
    int head=0,tail=1;
    qx[1]=a;qy[1]=b;
    vis[a][b]=true;
    while(head<tail)
    {
        int x=qx[++head],y=qy[head];
        ship[++cnt].x=x;ship[cnt].y=y;
        for(int i=0;i<4;i++)
        {
            int xx=x+ax[i];
            int yy=y+ay[i];
            if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!vis[xx][yy]&&map[xx][yy])
            {
                qx[++tail]=xx;
                qy[tail]=yy;
                vis[xx][yy]=true;
            }
        }
    }
}
int cmp(const node&aa,const node&bb)
{
    if(aa.x<bb.x)return 1;
    if(aa.x==bb.x&&aa.y<bb.y)return 1;
    return 0;
}
bool check()
{
    sort(ship+1,ship+cnt+1,cmp);
    int x2=0,y2=0,x3=0,y3=0;
    int x1=ship[1].x,y1=ship[1].y;
    int x4=ship[cnt].x,y4=ship[cnt].y;
    for(int i=1;i<=cnt;i++)
    {
        if(ship[i].x==x1&&ship[i].y==y4)
          x2=ship[i].x,y2=ship[i].y;
        if(ship[i].x==x4&&ship[i].y==y1)
          x3=ship[i].x,y3=ship[i].y;
    }
    if((!x2)||(!x3))return false;
    if((x4-x1+1)*(y4-y1+1)!=cnt)return false;
    return true;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
      {
          char c;cin>>c;
          if(c=='#')map[i][j]=1;
          else map[i][j]=0;
      }
    int tot=0;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        if(map[i][j]&&!vis[i][j])
        {
            tot++;
            cnt=0;
            bfs(i,j);
            if(!check())
            {
                printf("Bad placement.");
                return 0;
            }
        }
    printf("There are %d ships.",tot);
    return 0;
}
View Code

 

posted @ 2016-08-04 16:28  karles~  阅读(482)  评论(0编辑  收藏  举报