比赛的时候看错题意了,其实是个大水题
只用把每个点和(0,0)之前的和算出来,然后枚举左上角即可
/* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #define INF 1E9 using namespace std; int sum[2001][2003]; int main() { int n,m; while(~scanf("%d%d",&n,&m)&&n+m) { int x,y; scanf("%d%d",&x,&y); int i,j; getchar(); memset(sum,0,sizeof(sum)); for(i=1;i<=n;i++,getchar()) for(j=1;j<=m;j++) { if(getchar()=='*') { sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+1; } else sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]; } int ans=0; for(i=0;i<n;i++) for(j=0;j<m;j++) { if(i+x<=n&&j+y<=m&&sum[i+x][j+y]+sum[i][j]-sum[i+x][j]-sum[i][j+y]==(x*y))ans++; if(x!=y&&i+y<=n&&j+x<=m&&sum[i+y][j+x]+sum[i][j]-sum[i+y][j]-sum[i][j+x]==(x*y))ans++; } printf("%d\n",ans); } }