题解:
大致题意是给定两个封闭图形,求其各自拥有的.
个数以及共同拥有的.
个数
第一步 我们可以通过 d f s dfs dfs描出AB两个封闭图形的边,唯一要注意的一点就是当遇到十字路口时,按上一步的方向走即可
第二步我们可以不能发现从上往下、从左到右第一个
A
A
A或
B
B
B的边的位置的右下角必定为
A
A
A或
B
B
B的内部,所以我们只要以这个点为起点对
A
A
A图中的.
打上
1
1
1标记,
B
B
B图中的.
打上
2
2
2标记
(
d
f
s
)
(dfs)
(dfs)
最后枚举全图,既有 1 1 1又有 2 2 2的即为重合部分
代码:
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
//#include <random>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
#define PB push_back
#define MP make_pair
#define INF 1073741824
#define inf 1152921504606846976
#define pi 3.14159265358979323846
//#pragma comment(linker,"/STACK:10240000,10240000")
//mt19937 rand_(time(0));
const int N=3e5+7,M=2e6;
const long long mod=1e9+7;
inline int read(){int ret=0;char ch=getchar();bool f=1;for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-');for(;isdigit(ch);ch=getchar()) ret=(ret<<1)+(ret<<3)+ch-48;return f?ret:-ret;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}//逆元
//int head[N],NEXT[M],ver[M],tot;void link(int u,int v){ver[++tot]=v;NEXT[tot]=head[u];head[u]=tot;}
char str[120][120];
int mov_x[5]={0,-1,1,0};
int mov_y[5]={1,0,0,-1};
bool vis[3][120][120],res[3][120][120];
int n,m;
int ans[5];
bool judge(int x,int y,int num){
if(x<=0||y<=0||x>n||y>m||str[x][y]=='.'||vis[num][x][y]) return false;
return true;
}
bool JUDGE(int x,int y,int num){
if(x<=0||y<=0||x>n||y>m||vis[num][x][y]||res[num][x][y]) return false;
return true;
}
void dfs(int x,int y,int num,int pre){
int xx,yy;
int sum=0,zi;
for(int i=0;i<4;i++){
xx=x+mov_x[i];
yy=y+mov_y[i];
if(judge(xx,yy,num)){
sum++;
zi=i;
}
}
if(sum==3) {
zi=pre;
xx=x+mov_x[zi];
yy=y+mov_y[zi];
vis[num][xx][yy]=true;
dfs(xx,yy,num,zi);
}
else if(sum>0){
xx=x+mov_x[zi];
yy=y+mov_y[zi];
vis[num][xx][yy]=true;
dfs(xx,yy,num,zi);
}
}
void DFS(int x,int y,int num){
int xx,yy;
for(int i=0;i<4;i++){
xx=x+mov_x[i];
yy=y+mov_y[i];
if(JUDGE(xx,yy,num)){
res[num][xx][yy]=true;
DFS(xx,yy,num);
}
}
}
void solve(int num){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(vis[num][i][j]){
res[num][i+1][j+1]=true;
DFS(i+1,j+1,num);
return;
}
}
}
}
int main(){
//freopen("h.txt","r",stdin);
//ios::sync_with_stdio(false);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",str[i]+1);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(str[i][j]=='A'){
vis[1][i][j]=true;
dfs(i,j,1,-1);
}
else if(str[i][j]=='B'){
vis[2][i][j]=true;
dfs(i,j,2,-1);
}
}
}
solve(1);
solve(2);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(str[i][j]!='.') continue;
int tmp=0;
if(res[1][i][j]) tmp+=1;
if(res[2][i][j]) tmp+=2;
ans[tmp]++;
}
}
printf("%d %d %d\n",ans[1],ans[2],ans[3]);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}