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