DFS找联通块 注意大炮的互换规则 dfs可以融合一起 再加上sj的上限和qq的上限即可


using namespace std;
using ll=long long ;
const ll N=2e5+5;
int n;
string s[800];
vector<int>a;
vector<int>b;
int vis[500][500];


int dx[8]={0,1,1, 1, 0,-1,-1,-1};
int dy[8]={1,1,0,-1,-1,-1, 0, 1};

int sj_dfs(int x,int y){	
	int cut=1;	
	vis[x][y]=1;	
		for(int i=0;i<8;++i){
			int nx=x+dx[i];int ny=y+dy[i];
			if(nx>=0&&nx<4&&ny>=0&&ny<n&&!vis[nx][ny]&&s[nx][ny]=='*'){
				
				cut+=sj_dfs(nx,ny);
	
			}
		}		

return cut;	
}

int qq_dfs(int x,int y){	
	int cut=1;	
	vis[x][y]=1;	
	for(int i=0;i<8;++i){
		int nx=x+dx[i];int ny=y+dy[i];
		if(nx>=4&&nx<8&&ny>=0&&ny<n&&!vis[nx][ny]&&s[nx][ny]=='*'){
			
			cut+=qq_dfs(nx,ny);
			
		}
	}		
	
	return cut;	
}
	
void solve(){
	
	
	memset(vis,0,sizeof(vis));
	cin>>n;a.clear();b.clear();
	for(int i=0;i<8;++i)
	{
	cin>>s[i];
	}
	for(int i=0;i<4;++i){
		for(int j=0;j<n;++j)
		{
			if(s[i][j]=='*'&&!vis[i][j])a.push_back(sj_dfs(i,j));
		}
	}
	
	memset(vis,0,sizeof(vis));
	for(int i=4;i<8;++i){
		for(int j=0;j<n;++j)
		{
			if(s[i][j]=='*'&&!vis[i][j])b.push_back(qq_dfs(i,j));
		}
	}
//	for(auto A:a){
//			cout<<A<<' ';
//	}
//		cout<<'\n';
//	for(auto  B:b){
//		cout<<B<<' ';
//	}
	
//2 1
//3 1 1
	int sum=0;
	for(int B:b){
		sum+=B;
	}
	if(a.empty()){cout<<sum;return ;}
	if(a.size()>b.size()){cout<<-1;return ;}
	sort(b.begin(),b.end());
	for(int i=0;i<a.size()-1;++i){sum-=b[i];}
	cout<<sum;
	//但最后一次攻击后敌方全灭,所以最后一门炮幸存
}

int main(){
	
	ios::sync_with_stdio(false),cin.tie(nullptr);
	int T=1;
	
	
	while(T--){	
			
			solve();
		
		
	}
	
	
	
	return 0;
	
}