#P3101. 构成正方形的数量(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 170
            Accepted: 43
            Difficulty: 5
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>暴力枚举          
 
构成正方形的数量(100分)
暴力
已知正方形的一条边是可以确定正方形,假设两个点是(a1,a2),(b1,b2),那么可以确定 c1=a1+(a2-b2),c2=a2-(a1-b1) d1=b1+(a2-b2),d2=b2-(a1-b1) 或者 c1=a1+(a2-b2),c2=a2-(a1-b1); d1=b1+(a2-b2),d2=b2-(a1-b1); 因此一个正方形会被计算八遍,枚举任意两个点计算出来的结果/8就是答案,这个正方形可以二分也可以哈希,看到点的横坐标纵坐标范围很小考虑n4枚举任意两个点即可
代码如下
cpp
#include <bits/stdc++.h>
using namespace std;
#define N 15
map<pair<int,int>,int>mp;
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		int x,y;
		cin>>x>>y;
		mp[{x,y}]=1;
	}
	int ans=0;
	for(int a2=-10;a2<=10;a2++){
		for(int a1=-10;a1<=10;a1++){
			for(int b1=-10;b1<=10;b1++){
				for(int b2=-10;b2<=10;b2++){
					if(a1==b1&&a2==b2) continue;
					int c1=a1+(a2-b2),c2=a2-(a1-b1);
					int d1=b1+(a2-b2),d2=b2-(a1-b1);
					if(mp[{a1,a2}]&&mp[{b1,b2}]&&mp[{c1,c2}]&&mp[{d1,d2}]){
						ans++;
					}
					 c1=a1-(a2-b2),c2=a2+(a1-b1);
					 d1=b1-(a2-b2),d2=b2+(a1-b1);
					if(mp[{a1,a2}]&&mp[{b1,b2}]&&mp[{c1,c2}]&&mp[{d1,d2}]){
						ans++;
					}
				}
			}
		}
	}
	cout<<ans/8<<'\n';
	return 0;
}
python
def main():
    n = int(input())
    mp = {}
    for _ in range(n):
        x, y = map(int, input().split())
        mp[(x, y)] = 1
    ans = 0
    for a2 in range(-10, 11):
        for a1 in range(-10, 11):
            for b1 in range(-10, 11):
                for b2 in range(-10, 11):
                    if a1 == b1 and a2 == b2:
                        continue
                    c1 = a1 + (a2 - b2)
                    c2 = a2 - (a1 - b1)
                    d1 = b1 + (a2 - b2)
                    d2 = b2 - (a1 - b1)
                    if (a1, a2) in mp and (b1, b2) in mp and (c1, c2) in mp and (d1, d2) in mp:
                        ans += 1
                    
                    c1 = a1 - (a2 - b2)
                    c2 = a2 + (a1 - b1)
                    d1 = b1 - (a2 - b2)
                    d2 = b2 + (a1 - b1)
                    if (a1, a2) in mp and (b1, b2) in mp and (c1, c2) in mp and (d1, d2) in mp:
                        ans += 1
    print(ans // 8)
if __name__ == "__main__":
    main()
java
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        Map<Pair, Integer> mp = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            mp.put(new Pair(x, y), 1);
        }
        int ans = 0;
        for (int a2 = -10; a2 <= 10; a2++) {
            for (int a1 = -10; a1 <= 10; a1++) {
                for (int b1 = -10; b1 <= 10; b1++) {
                    for (int b2 = -10; b2 <= 10; b2++) {
                        if (a1 == b1 && a2 == b2) continue;
                        int c1 = a1 + (a2 - b2);
                        int c2 = a2 - (a1 - b1);
                        int d1 = b1 + (a2 - b2);
                        int d2 = b2 - (a1 - b1);
                        if (mp.containsKey(new Pair(a1, a2)) && 
                            mp.containsKey(new Pair(b1, b2)) && 
                            mp.containsKey(new Pair(c1, c2)) && 
                            mp.containsKey(new Pair(d1, d2))) {
                            ans++;
                        }
                        c1 = a1 - (a2 - b2);
                        c2 = a2 + (a1 - b1);
                        d1 = b1 - (a2 - b2);
                        d2 = b2 + (a1 - b1);
                        if (mp.containsKey(new Pair(a1, a2)) && 
                            mp.containsKey(new Pair(b1, b2)) && 
                            mp.containsKey(new Pair(c1, c2)) && 
                            mp.containsKey(new Pair(d1, d2))) {
                            ans++;
                        }
                    }
                }
            }
        }
        System.out.println(ans / 8);
    }
    static class Pair {
        int x, y;
        Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Pair)) return false;
            Pair pair = (Pair) o;
            return x == pair.x && y == pair.y;
        }
        @Override
        public int hashCode() {
            return 31 * x + y;
        }
    }
}
        题目内容
输入N个互不相同的二维整数坐标,求这N个坐标可以构成的正方形数量。(内积只为零的的两个向量垂直)
输入描述
第一行输入为N,N代表坐标数量,N为正整数。
N≤100
之后的N行输入为坐标x,y 以空格分隔,x,y为整数
−10≤x,y≤10
输出描述
输出可以构成的正方形数量
样例1
输入
 3
 1 3
 2 4
 3 1
输出
0
说明
3个点不足以构成正方形
样例2
输入
4
0 0
1 2
3 1
2 -1
输出
1
说明
此4点可构成正方形