• Equilateral Triangles


    Equilateral Triangles

    题意: 求所有三个点哈密顿距离相等的无序三元点对个数

    推论1: 到平面中一点((x,y))哈密顿距离为(d)的点,构成一个以((x,y))为中心,(d)为半对角线长的菱形

    菱形不好搞,转一下,令旋转后的点(x'=x+y,y'=x-y),(也就是曼哈顿距离转切比雪夫距离)

    这样得到的就是一个正方形了

    推论2: 选出的三点中,一定存在两个点(x)或者(y)坐标相同

    如果选出点(A,B)不满足,由下图可以看到,可行的部分(就是相交部分(C1,C2))也必然满足

    te1.png

    接下来以(x)相同为例,枚举点(A,B),设其距离为(d)

    te2.png

    可以看到比较显然就是两条红色的相交线段,(O(n^3))枚举(A,B)两点后,直接用前缀和维护即可

    对于(x)相同,对于(y)相同分别做一次即可,注意考虑的时候不要把(x,y)都有相同的算两次

    #include<bits/stdc++.h>
    using namespace std;
    #pragma GCC optimize(2)
    #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
    
    const int N=610;
    
    int n;
    char A[N][N],B[N][N];
    int S[N][N];
    int D[N],C;
    
    int main() {
    	scanf("%d",&n);
    	rep(i,1,n) {
    		scanf("%s",A[i]+1);
    		rep(j,1,n) if(A[i][j]=='*') B[i+j][i-j+n]=1;
    	}
    	int ans=0;
    	rep(i,1,n*2) rep(j,1,n*2) S[i][j]=S[i][j-1]+B[i][j];
    	rep(i,1,n*2) {
    		C=0;
    		rep(x,1,n*2) if(B[i][x]) D[++C]=x;
    		rep(a,1,C) rep(b,a+1,C) {
    			int d=D[b]-D[a];
    			i-d>=1 && (ans+=S[i-d][D[b]]-S[i-d][D[a]-1]);
    			i+d<=n*2 && (ans+=S[i+d][D[b]]-S[i+d][D[a]-1]);
    		}
    	}
    	rep(i,1,n*2) rep(j,1,n*2) S[i][j]=S[i][j-1]+B[j][i];
    	rep(i,1,n*2) {
    		C=0;
    		rep(x,1,n*2) if(B[x][i]) D[++C]=x;
    		rep(a,1,C) rep(b,a+1,C) {
    			int d=D[b]-D[a];
    			i-d>=1 && (ans+=S[i-d][D[b]-1]-S[i-d][D[a]]);
    			i+d<=n*2 && (ans+=S[i+d][D[b]-1]-S[i+d][D[a]]);
    		}
    	}
    	printf("%d
    ",ans);
    }
    
    
    
    
    
    
  • 相关阅读:
    use paramiko to connect remote server and execute command
    protect golang source code
    adjust jedi vim to python2 and python3
    install vim plugin local file offline
    add swap file if you only have 1G RAM
    datatables hyperlink in td
    django rest framework custom json format
    【JAVA基础】网络编程
    【JAVA基础】多线程
    【JAVA基础】String类的概述和使用
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13729423.html
Copyright © 2020-2023  润新知