#P3101. 构成正方形的数量(100分)
-
1000ms
Tried: 182
Accepted: 44
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点可构成正方形