一道简单的贪心+搜索题 我们可以让齐齐每次以最小的炮数换掉司机最大的炮数
首先 对齐齐和司机的阵地进行搜索 看可以分成多少块 每块内的炮一炸一起炸 块外的的炮不受影响
题目就相当于每次用齐齐的最小连通块换司机的最大连通块
代码有详细注释

#include <bits/stdc++.h>
#define ll long long
const int M=110;
const int N=1000;
using namespace std;
int m,a[10][M],b[10][M],f1[N],f2[N];
string s;
void f11(int x,int y,int k)
{
    for(int i=x-1;i<=x+1;++i)
    {
        for(int j=y-1;j<=y+1;++j)
           if(a[i][j]){a[i][j]=0;f1[k]++;f11(i,j,k);}
    }
}
void f22(int x,int y,int k)
{
    for(int i=x-1;i<=x+1;++i)
    {
        for(int j=y-1;j<=y+1;++j)
           if(b[i][j]) {b[i][j]=0;f2[k]++;f22(i,j,k);}
    }
}
int main()
{
   cin>>m;
   for(int i=1;i<=4;++i)
   {
       cin>>s;
       for(int j=0;j<m;++j)
       {
         if(s[j]=='*') a[i][j+1]=1;
       }
   }
   for(int i=1;i<=4;++i)
   {
       cin>>s;
       for(int j=0;j<m;++j)
       {
         if(s[j]=='*') b[i][j+1]=1;
       }
   }
   int ins1=0,ins2=0;
   for(int i=1;i<=4;++i)
   {
       for(int j=1;j<=m;++j)
       {
           if(a[i][j]){a[i][j]=0; f1[++ins1]=1;f11(i,j,ins1);}///每块有几个炮
       }
   }
   for(int i=1;i<=4;++i)
   {
       for(int j=1;j<=m;++j)
       {
           if(b[i][j]){b[i][j]=0; f2[++ins2]=1;f22(i,j,ins2);}///每块有几个炮
       }
   }
   //for(int i=1;i<=ins1;++i)cout<<f1[i]<<" ";cout<<endl;
  // for(int i=1;i<=ins2;++i)cout<<f2[i]<<" ";cout<<endl;
   if(ins1>ins2) {cout<<-1<<endl;return 0;}
   sort(f1+1,f1+1+ins1);sort(f2+1,f2+1+ins2);///用最小的换最大的
   int ans=0;
   for(int i=ins1;i<=ins2;++i) ans+=f2[i];///剩下的就是齐齐炮数大的块
   cout<<ans<<endl;
    return 0;
}