先把所有红色连通块找出来,然后统计每个红块“挨着”的蓝格数量:如果存在一个红块能挨到全部蓝格,红方先手第一步直接全染红,答案就是 Red。
如果一开始全蓝就是 Blue;否则红方做不到一步清场时,蓝方也永远不可能把红格变蓝,结果是 Draw。
void solve(){
int n,m;cin>>n>>m;
vs g(n);
for(int i=0;i<n;++i)cin>>g[i];
int r=0,b=0;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(g[i][j]=='#')++r;
else ++b;
}
}
if(b==0){
cout<<"Red"<<endl;
return;
}
if(r==0){
cout<<"Blue"<<endl;
return;
}
vvi id(n,vi(m,-1));
int c=0;
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
queue<pii> q;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(g[i][j]=='#'&&id[i][j]==-1){
id[i][j]=c;
q.push({i,j});
while(!q.empty()){
pii u=q.front();q.pop();
for(int k=0;k<4;++k){
int ni=u.fi+dx[k],nj=u.se+dy[k];
if(ni<0||ni>=n||nj<0||nj>=m)continue;
if(g[ni][nj]!='#'||id[ni][nj]!=-1)continue;
id[ni][nj]=c;
q.push({ni,nj});
}
}
++c;
}
}
}
vi cnt(c,0);
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(g[i][j]!='.')continue;
int t=0,a[4];
for(int k=0;k<4;++k){
int ni=i+dx[k],nj=j+dy[k];
if(ni<0||ni>=n||nj<0||nj>=m)continue;
if(g[ni][nj]!='#')continue;
int v=id[ni][nj],ok=1;
for(int k=0;k<t;++k){
if(a[k]==v){
ok=0;
break;
}
}
if(ok)a[t++]=v;
}
for(int k=0;k<t;++k)++cnt[a[k]];
}
}
for(int i=0;i<c;++i){
if(cnt[i]==b){
cout<<"Red"<<endl;
return;
}
}
cout<<"Draw"<<endl;
}

京公网安备 11010502036488号