原题
思路
可以看作大炮形成的八连通 齐齐一方每次统计连通块中大炮的数量 尽量先用大炮少的连通块攻击 若七七一方连通块数量小于司机一方,则其不可能获胜
代码
# include <bits/stdc++.h>
# define x first
# define y second
using namespace std;
const int N = 450 ;
typedef pair< int , int > PII;
char a[ N] [ N] , b[ N] [ N] ;
PII q[ N * N] ;
bool st[ N] [ N] ;
int ca[ N] , cb[ N] ;
int m;
vector< int > u;
int bfs ( int sx, int sy, int u)
{
int res = 1 ;
int hh = 0 , tt = 0 ;
q[ 0 ] = { sx, sy} ;
st[ sx] [ sy] = true ;
while ( hh <= tt)
{
auto t = q[ hh ++ ] ;
for ( int i = t. x - 1 ; i <= t. x + 1 ; i ++ )
for ( int j = t. y - 1 ; j <= t. y + 1 ; j ++ )
{
if ( i == t. x && j == t. y) continue ;
if ( i >= 4 + u || i < u || j >= m || j < 0 ) continue ;
if ( a[ i] [ j] == '.' || st[ i] [ j] ) continue ;
q[ ++ tt] = { i, j} ;
st[ i] [ j] = true ;
res ++ ;
}
}
return res;
}
int main ( )
{
cin >> m;
int cnt = 0 , cot = 0 ;
for ( int i = 0 ; i < 8 ; i ++ ) cin >> a[ i] ;
for ( int i = 0 ; i < 4 ; i ++ )
for ( int j = 0 ; j < m; j ++ )
{
if ( ! st[ i] [ j] && a[ i] [ j] == '*' )
{
bfs ( i, j, 0 ) ;
cnt ++ ;
}
}
for ( int i = 4 ; i < 8 ; i ++ )
for ( int j = 0 ; j < m; j ++ )
{
if ( ! st[ i] [ j] && a[ i] [ j] == '*' )
{
u. push_back ( bfs ( i, j, 4 ) ) ;
}
}
cot = u. size ( ) ;
if ( cnt > cot) puts ( "-1" ) ;
else
{
sort ( u. begin ( ) , u. end ( ) ) ;
int ans = 0 ;
for ( int i = cnt - 1 ; i < cot; i ++ ) ans += u[ i] ;
cout << ans << endl;
}
return 0 ;
}