题目大意
两方玩游戏,每次都会使用己方的大炮攻击对方,会产生以攻击点为中心的3*3的波及区域,求我们最多能保留多少大炮并且将对方的大炮消耗完
解题思路
因为我们用大炮攻击对方时,对方就会获得我们这枚大炮的视野,所以我们要尽量用连通块中数量较少的大炮去攻击对方
#include<bits/stdc++.h>
using namespace std;
int m;
char qq[5][110];
char sj[5][110];
int dx[]={-1,1,0,0,-1,-1,1,1};
int dy[]={0,0,-1,1,-1,1,-1,1};
bool vis[5][110];
int bfs(char a[][110],int x,int y){
int cnt=1;
vis[x][y]=1;
queue<pair<int,int>>q;
q.push({x,y});
while(!q.empty()){
pair<int,int> it=q.front(); q.pop();
for(int i=0;i<8;++i){
int nx=it.first+dx[i];
int ny=it.second+dy[i];
if(nx>=1&&nx<=4&&ny>=1&&ny<=m&&!vis[nx][ny]&&a[nx][ny]=='*'){
vis[nx][ny]=1;
q.push({nx,ny});
cnt++;
}
}
}
return cnt;
}
int main(){
cin>>m;
for(int i=1;i<=4;++i){
for(int j=1;j<=m;++j){
cin>>sj[i][j];
}
}
memset(vis,0,sizeof(vis));
int k=0;
for(int i=1;i<=4;++i){
for(int j=1;j<=m;++j){
if(sj[i][j]=='*'&&!vis[i][j]){
k++; //我们仅需要记录司机有多少个大炮
bfs(sj,i,j);
}
}
}
for(int i=1;i<=4;++i){
for(int j=1;j<=m;++j){
cin>>qq[i][j];
}
}
memset(vis,0,sizeof(vis));
int sum=0;
vector<int>liantong;
for(int i=1;i<=4;++i){
for(int j=1;j<=m;++j){
if(qq[i][j]=='*'&&!vis[i][j]){
int t=bfs(qq,i,j); //t记录的是这个点的大炮的连通块中有多少个大炮
sum+=t; //sum连加记录总共有多少个大炮
liantong.push_back(t);
}
}
}
if(liantong.size()<k) cout<<-1<<endl;
else{
sort(liantong.begin(),liantong.end());
for(int i=0;i<k-1;++i) //合并成k个连通块 总共需要合并k-1次
sum-=liantong[i];
cout<<sum<<endl;
}
return 0;
}

京公网安备 11010502036488号