题意
数等腰直角三角形个数,要求顶点无黑点,边上无黑点。
题解
作为一个暴力计数问题,一个很重要的思想是不重复不遗漏。
这样想到每个点作为直角顶点的话有八种形态,不同直角顶点的三角形显然不是相同的直角三角形。这样只要枚举完直角顶点后,再枚举直角边长/斜边上的高就好了。
然后就是如何判断黑点的问题,解决方案就是前缀和。
和输入一样黑取1,白取0,(我觉得这确实算一个提示。。。)计算横竖两条对角线四个前缀和。然后只要O(1)就能判定是否有黑点
于是
一个O(n^3)的做法就有了。
好了剩下的问题就是编程代码问题,包括各种边界判定啦神马的,不过考虑到八种形态的旋转对称性,三角形旋转不好弄,矩形旋转简单啊,运动是相对的。。。
可以用旋转矩阵的方法去做,这样代码难度和长度都可以接受了。
不过我个逗比居然把旋转写成了转置。。。查了好久。。。OTZ
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#include <set>
using namespace std;
int Matrix [405][405];
int temp[405][405];
void rotate(int n, int m) {
memset(temp, 0, sizeof(temp));
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
temp[j][n - i + 1] = Matrix[i][j];
}
}
memcpy(Matrix, temp, sizeof(temp));
}
void Read(int &a){
char ch;
a = 0;
ch = getchar();
while( !(ch >= '0' && ch <= '9') ) ch = getchar();
while((ch >= '0' && ch <= '9') ){
a = a * 10 + ch - '0';
ch = getchar();
}
}
int row[405][405],col[405][405],dia1[405][405],dia2[405][405];
long long cal(int m,int n)
{
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
memset(dia2,0,sizeof(dia1));
memset(dia1,0,sizeof(dia2));
for (int i=1;i<=m+1;i++)
for (int j=1;j<=n+1;j++)
{
row[i][j]=row[i][j-1]+Matrix[i][j];
col[i][j]=col[i-1][j]+Matrix[i][j];
dia1[i][j]=dia1[i-1][j-1]+Matrix[i][j];
dia2[i][j]=dia2[i-1][j+1]+Matrix[i][j];
}
long long cnt=0;
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
{
if (Matrix[i][j]) continue;
for (int k=1;k<min(i,j);k++)
{
if ((row[i][j]-row[i][j-k-1]==0)&&(col[i][j]-col[i-k-1][j]==0)&&(dia2[i][j-k]-dia2[i-k-1][j+1]==0))
cnt++;
if (j+k<=n)
if ((row[i-k][j+k]-row[i-k][j-k-1]==0)&&(dia1[i][j]-dia1[i-k-1][j-k-1]==0)&&(dia2[i][j]-dia2[i-k-1][j+k+1]==0))
cnt++;
}
}
return cnt;
}
int main()
{
//freopen("input","r",stdin);
//freopen("output","w",stdout);
int m,n;
Read(m),Read(n);
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
{
char ch=getchar();
if (ch=='\n') ch=getchar();
Matrix[i][j]=ch-'0';
}
/*for (int i=0;i<m;i++)
for (int j=0;j<n;j++)
cout<<Matrix[i][j]<<endl;*/
long long ans=0;
ans+=cal(m,n);
rotate(m,n);
ans+=cal(n,m);
rotate(n,m);
ans+=cal(m,n);
rotate(m,n);
ans+=cal(n,m);
cout<<ans<<endl;
return 0;
}