今、実際には疑問がある\(パスカル\)問題を解決するにはされていません\(C ++ \)問題のケース・ソリューション、小さなこんにゃくは、それを破壊します。
カテゴリートーク:タイトルを考えます
この質問は思考のテストで、話題に戻り、我々は行われません埋める方法を検討する必要があり、最終的に周囲は唯一、再びこの数字をそれを見つけることができます。目標点いくつかの状況を考えてみます。
\(0.5 \)の三点を中心に現在ある\(\)または4つの\(\)とき:確かに、この時点までの直接使用に来ない\(\)を記入します。
\(1 \)現在の点は、二つの中間点の間に挟まれたこの点は、別個の充填された後、両側が発生するか否かを判定する(X \)\一方が充填された後ならば、この点は、スキップされ、原因この時点では、再検索し、再検討することです。
\(2 \)二つの隣接によって現在のポイント\は、(A \)を一緒にクランプし、現在時点の周りに充填する8員ない\(X- \) 、その後直接充填。
\(3 \)二つの隣接することにより、現在のポイント\(\)が一緒にクランプしたときに、現在のポイントを中心に記入8員が\(X \) 、この点は確かに、通じだろうどんなに出ているためストレッチ、そして最終的にここからそれを回避するために、最後でなければならない(X- \)\。
\(4 \)は、点の周り現在存在する\(\)またはいいえ(\ \) 、次いでケア、等の最初の点は、また、再び検索するであろう。
複雑証明:各点は一回のみとなるため\(A \) 、次いで外側に検索するので複雑である\(O(NM)\)
マップのうちの処理のために、我々は、各点の判定とライン上のいくつかの後になります。各点は、この点の周りの回数に等しい後\(8員\)連続\(\)セグメントの数。
最後に、魔法のコード:
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
int n,m;
char mp[N][N];
void dfs(int x,int y){
int cnt=0;
int u[5];
for(int i=0;i<4;++i){
int nx=x+dx[i],ny=y+dy[i];
if(mp[nx][ny]=='A'){
u[++cnt]=i;
}
}
if(cnt==2){
if(u[2]-u[1]==2)return;
if(mp[x-dx[u[1]]-dx[u[2]]][y-dy[u[1]]-dy[u[2]]]!='.')return;
}
if(cnt>1){
mp[x][y]='A';
for(int i=0;i<4;++i){
int nx=x+dx[i],ny=y+dy[i];
if(nx>1&&nx<n&&ny>1&&ny<m&&mp[nx][ny]=='.'){
dfs(nx,ny);
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;++i){
scanf("%s",mp[i]+1);
}
for(int i=2;i<n;++i){
for(int j=2;j<m;++j){
if(mp[i][j]=='.')dfs(i,j);
}
}
int ans=0;
for(int x=1;x<=n;++x){
for(int y=1;y<=m;++y){
int js=0;
if(mp[x][y]=='.'){
int u[5],cnt=0;
for(int i=0;i<4;++i){
int nx=x+dx[i],ny=y+dy[i];
if(mp[nx][ny]=='A')u[++cnt]=i;
}
if(cnt==1){
js=1;
}else if(cnt==2&&abs(u[2]-u[1])==2){
js=2;
}else if(cnt==2)js=1;
for(int i=0;i<4;++i){
int nx=x+dx[i],ny=y+dy[i];
if(mp[nx][ny]!='A'){
nx=x+dx[(i+1)%4],ny=y+dy[(i+1)%4];
if(mp[nx][ny]!='A'){
nx=x+dx[i]+dx[(i+1)%4],ny=y+dy[i]+dy[(i+1)%4];
if(mp[nx][ny]=='A'){
js++;
}
}
}
}
ans+=js;
}
}
}
cout<<ans<<endl;
}