题目
题解
虽然说是一道白银,但是我刚看到的时候还是毛有思路啊!!
遍历矩阵,找一个没到过的格子(xx,yy)作为当前矩形的左上角,开始BFS,如果过程中出现x< xx||y< yy的话就是不可能的(手画一下就可以看出),如果没有出现这样的情况,就记录x坐标,y坐标的最大值maxx,maxy,然后记录一下到过的格子数cnt,如果cnt==(maxx-xx+1)*(maxy-yy+1)说明这个矩形是满的,当前矩形符合要求,一个一个找就行了
代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1000+10;
const int dx[]={-1,0,1,0};
const int dy[]={0,1,0,-1};
char map[maxn][maxn];
int vis[maxn][maxn],n,m;
struct Node{
int x,y;
Node(int x=0,int y=0):x(x),y(y){}
};
int inside(int x,int y){return x>=1&&x<=n&&y>=1&&y<=m;}
int BFS(int xx,int yy)
{
int maxx=xx,maxy=yy,cnt=0;
queue<Node>q;
q.push(Node(xx,yy));
vis[xx][yy]=1;
while(!q.empty())
{
Node k=q.front();q.pop();
cnt++;
for(int i=0;i<4;i++)
{
int nx=k.x+dx[i],ny=k.y+dy[i];
if(inside(nx,ny)&&map[nx][ny]=='#'&&!vis[nx][ny])
{
vis[nx][ny]=1;
maxx=max(maxx,nx);
maxy=max(maxy,ny);
q.push(Node(nx,ny));
if(nx<xx||ny<yy) return false;
}
}
}
if(cnt==(maxx-xx+1)*(maxy-yy+1)) return true;
return false;
}
int main()
{
cin>>n>>m;
int cnt=0;
for(int i=1;i<=n;i++)scanf("%s",map[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!vis[i][j]&&map[i][j]=='#')
if(!BFS(i,j))
{
printf("Bad placement.\n");return 0;
}
else cnt++;
printf("There are %d ships.",cnt);
return 0;
}