解析:
对于每一个大炮受到攻击,那么以它为中心的3*3方格都会收到波及,所以我们求一下连通块,以及每个连通块的个数。
我们求出齐齐的连通块数量为 tot1
求出司机的连通块数量为 tot
如果tot1<tot 那么齐齐肯定不能摧毁司机所有的大炮 输出-1
对于tot1>tot 。 我们希望剩下来的大炮尽量多,所以我们按照每个连通块的个数从小到大排序,让小的去解决。那么剩下的就是最大的
#include<bits/stdc++.h>
using namespace std;
const int N=1100;
int size[N];
char s[N][N];
int vis[N][N];
int dx[8]={0,1,0,-1,-1,1,1,-1};
int dy[8]={1,0,-1,0,1,1,-1,-1};
int m,cnt;
int a[N],b[N],tot,tot1;
void dfs(int x,int y,int &ans,int k)
{
if(s[x][y]=='.') return ;
vis[x][y]=true;
for(int i=0;i<8;i++)
{
int xx=dx[i]+x;
int yy=dy[i]+y;
if(xx<k||xx>=k+4||yy<0||y>=m||vis[xx][yy]) continue;
vis[xx][yy]=true;
if(s[xx][yy]=='*') ans++;
dfs(xx,yy,ans,k);
}
}
int main()
{
cin>>m;
for(int i=0;i<8;i++) cin>>s[i];
for(int i=0;i<4;i++)
{
for(int j=0;j<m;j++)
{
if(s[i][j]=='*'&&!vis[i][j])
{
cnt=1;
dfs(i,j,cnt,0);
a[++tot]=cnt;
}
}
}
for(int i=4;i<8;i++)
{
for(int j=0;j<m;j++)
{
if(s[i][j]=='*'&&!vis[i][j])
{
cnt=1;
dfs(i,j,cnt,4);
b[++tot1]=cnt;
}
}
}
if(tot1<tot) cout<<-1<<endl;
else
{
sort(b+1,b+1+tot1);
int ans=0;
for(int i=tot;i<=tot1;i++) ans+=b[i];
cout<<ans<<endl;
}
}