题解 CF11C

题意

链接
你有一个\(01\)矩阵。里面有多少个正方形?其中正方形的边用\(1\)表示:其中有两种正方形

  • 这种的
0000000
0111100 
0100100
0100100 
0111100
0000000 有1个正方形
  • 这种的
0000000
0010000
0101000
0010000
0000000 有一个正方形

所以模拟即可

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#define ll long long
#define maxn 10050
#define inf 2147483647
#define mod 10003
#define eps 1e-6
#define pi acos(-1.0)
#define de(x) ((x)*(x))
using namespace std; 
inline int read(){
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
    return x*f;
} 
const int dx[9]={0,1,1,1,0,0,-1,-1,-1};
const int dy[9]={0,1,0,-1,1,-1,1,0,-1};
int n,m,t;
char s[550][550];
inline int dfs(int x,int y,int &t){//不用我说
	if(s[x][y]!='1') return 0;
	s[x][y]='2'; t++;
	for(int i=1;i<=8;i++)
	if(x+dx[i]>=0&&y+dy[i]>=0&&x+dx[i]<n&&y+dy[i]<m)
		dfs(x+dx[i],y+dy[i],t);
	return 0;
}
inline int check1(int x,int y,int cnt){//看着看着就懂了,下同
	if(x+cnt>=n||y+cnt>=m) return 0;
	for(int i=1;i<=cnt;i++){
		if(s[x][y+i]!='2') return 0;
		if(s[x+cnt][y+i]!='2') return 0;
		if(s[x+i][y]!='2') return 0;
		if(s[x+i][y+cnt]!='2') return 0; 
	}
	return 1;
}
inline int check2(int x,int y,int cnt){/
	if(y+cnt>=m||x+cnt*2>=n||y-cnt<0||s[x+cnt*2][y]!='2') return 0;
	for(int i=1;i<=cnt;i++){
		if(s[x+i][y+i]!='2') return 0;
		if(s[x+i][y-i]!='2') return 0;
		if(s[x+2*cnt-i][y-i]!='2') return 0;
		if(s[x+2*cnt-i][y+i]!='2') return 0;
	}
	return 1;
}
signed main(){
	int T=read();
	while(T--){
		n=read(); m=read();
		int ans=0;
		for(int i=0;i<n;i++) cin>>s[i];
		for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		if(s[i][j]=='1'){
			t=0; dfs(i,j,t);
			if(t%4==0&&t<=4*min(m,n)){
				ans+=check1(i,j,t/4);
				ans+=check2(i,j,t/4); 
			}
		}
		printf("%d\n",ans);
	}
    return 0;
}

posted @ 2019-09-04 16:06  云山乱  阅读(378)  评论(0编辑  收藏  举报