P1331 海战 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路
这一题就是在寻找有多少个色块(在这一题指的就是船)的基础之上,加了一个前提条件,色块必须得是方块型的,因为题目规定了每只船却不能碰到其它的船,棋盘上只存在相互之间不能接触的方形。所以每次找到一个色块之后,得去判断这个色块是不是方块型的。我每次找色块的时候,用一个一维数组记录色块每行的长度,然后完整的找到一个色块之后,再去比较它每行的长度是否相等,如果不相等,就直接判断船只放置的不正确,否则就成功找到一条船。
代码实现
#include<bits/stdc++.h>
using namespace std;
char s[1005][1005];
int r,c,vis1[1005][1005],vis2[1005],sum,cnt;
int d[4][4]={{0,1},{1,0},{0,-1},{-1,0}};
void dfs(int u,int v)//找船只
{
if(u<0||u>=r||v<0||v>=c)
{
return;
}
vis1[u][v]=1;//标记该点已经成为了某一条船的一部分
vis2[u]++;//通过记录某条船每行的长度,方便判断某条船是否方块状的
for(int i=0;i<4;i++)
{
int uu=u+d[i][0];
int vv=v+d[i][1];
if(uu>=0&&uu<r&&vv>=0&&vv<c&&vis1[uu][vv]==0&&s[uu][vv]=='#')
{
dfs(uu,vv);
}
}
}
int main()
{
scanf("%d %d",&r,&c);
for(int i=0;i<r;i++)
{
scanf("%s",s[i]);
}
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
if(vis1[i][j]==0&&s[i][j]=='#')
{
dfs(i,j);
sum++;
int flag=0;
for(int k=0;k<r;k++)
{
if(vis2[k]>0&&flag==0)//找出该条船每行的长度
{
cnt=vis2[k];
flag=1;
}
if(vis2[k]>0&&flag==1)
{
if(vis2[k]!=cnt)//每行的长度不相同,直接输出Bad placement
{
printf("Bad placement.");
return 0;
}
vis2[k]=0;//去除标记,方便下一条船的寻找
}
}
cnt=0;//去除标记
}
}
}
printf("There are %d ships.",sum);
return 0;
}