题意:给出一个整数m,再给出8行字符串,前4行为司机基地情况,后四行为齐齐基地情况,求齐齐在摧毁司机全部大炮后最多剩多少门大炮?(无法全部摧毁司机大炮则输出-1)
思路:dfs求出司机基地有多少个大炮连通块,再用dfs求出齐齐每一个大炮连通块的大炮个数并保存,由于保存最多的大炮,使用的大炮所在连通块在下次司机的攻击下会被摧毁,所以齐齐首先使用大炮连通块的大炮个数最少的攻击司机基地大炮。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; char s[15][1005], b[15][1005], dx[9]={1,1,1,0,0,0,-1,-1,-1}, dy[9]={1,0,-1,1,0,-1,1,0,-1}; int m; void dfs(int x,int y) { s[x][y]='.'; for(int i=0;i<9;i++) { int x2=x+dx[i], y2=y+dy[i]; if(x2<4&&x2>=0&&y2<m&&y2>=0&&s[x2][y2]=='*') { dfs(x2,y2); } } } int dfs1(int x,int y) { int z=1; b[x][y]='.'; for(int i=0;i<9;i++) { int x2=x+dx[i], y2=y+dy[i]; if(x2<4&&x2>=0&&y2<m&&y2>=0&&b[x2][y2]=='*') { z=z+dfs1(x2,y2); } } return z; } int a[10005], ji=0; int main() { scanf("%d",&m); for(int i=0; i<8; i++) { if(i<4) scanf("%s",s[i]); else scanf("%s",b[i-4]); } int z=0; for(int i=0;i<4;i++) { for(int j=0;j<m;j++) { if(s[i][j]=='*') { dfs(i,j); z++; } } } for(int i=0;i<4;i++) { for(int j=0;j<m;j++) { if(b[i][j]=='*') { a[ji++]=dfs1(i,j); } } } if(z>ji) { printf("-1\n"); } else { sort(a,a+ji); int ans=0; for(int i=max(0,z-1);i<ji;i++) { ans+=a[i]; } printf("%d\n",ans); } return 0; }