1. 程式人生 > >atcoder tenka1 2018 e Equilateral - 字首和

atcoder tenka1 2018 e Equilateral - 字首和

題目大意:給一張黑白網格圖,問有多少黑點的無序三元組,兩兩曼哈頓距離相等。300。
題解:轉切比雪夫距離,發現一定有至少兩個點的連向平行於座標軸。
列舉計算即可,注意等腰直角三角形的情況若不處理會被計兩次。

#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define db long double
#define pb push_back
#define mp make_pair #define fir first #define sec second #define debug(x) cerr<<#x<<"="<<x #define sp <<" " #define ln <<endl using namespace std; typedef pair<int,int> pii; typedef set<int>::iterator sit; inline int inn() { int x,ch;while((ch=gc)<'0'||
ch>'9'); x=ch^'0';while((ch=gc)>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^'0');return x; } #define Ss(x,y) (x>=1&&x<=n&&y>=1&&y<=m&&v[x][y]) const int N=1010;int v[N][N],s[N][N];char str[N][N]; inline int S(int a,int b,int c,int d) { return
s[c][d]-s[a-1][d]-s[c][b-1]+s[a-1][b-1]; } int main() { int n=inn(),m=inn(),ans=0; rep(i,1,n) scanf("%s",str[i]+1); rep(i,1,n) rep(j,1,m) v[i+j][i-j+m]=(str[i][j]=='#'); int nn=n+m,mm=n-1+m;n=nn,m=mm; rep(i,1,n) rep(j,1,m) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+v[i][j]; rep(i,1,n) rep(j,1,m) rep(k,j+2,m) { int d=k-j;if(!v[i][j]||!v[i][k]) continue; if(i-d>=1) ans+=S(i-d,j+1,i-d,k-1); if(i+d<=n) ans+=S(i+d,j+1,i+d,k-1); } rep(i,1,m) rep(j,1,n) rep(k,j+2,n) { int d=k-j;if(!v[j][i]||!v[k][i]) continue; if(i-d>=1) ans+=S(j+1,i-d,k-1,i-d); if(i+d<=m) ans+=S(j+1,i+d,k-1,i+d); } rep(i,1,n) rep(j,1,m) { if(!v[i][j]) continue; rep(d,1,max(n,m)) { if(Ss(i-d,j)&&Ss(i,j-d)) ans++; if(Ss(i-d,j)&&Ss(i,j+d)) ans++; if(Ss(i+d,j)&&Ss(i,j-d)) ans++; if(Ss(i+d,j)&&Ss(i,j+d)) ans++; } } return !printf("%d\n",ans); }