zoukankan      html  css  js  c++  java
  • 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);
    }
    
    
    
    
    
    
  • 相关阅读:
    Java判断一个实体类对象实例的所有成员变量是否为空
    正则表达式 整数
    将定时任务cron 解析成中文
    如何使用html定义一个红色小圆点
    Oracle获取当前日期前一个月的全部日期
    京东系统架构师如何让笨重的架构变得灵巧
    POI使用详解
    Java Excel 列号数字与字母互相转换
    使用exe4j将java项目打成exe执行程序
    Address already in use: JVM_Bind错误的解决
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13729423.html
Copyright © 2011-2022 走看看