(B卷,100分)- 构成正方形的数量(Java & JS & Python)

题目描述

输入N个互不相同的二维整数坐标,求这N个坐标可以构成的正方形数量。[内积为零的的两个向量垂直]

输入描述

第一行输入为N,N代表坐标数量,N为正整数。N <= 100

之后的 K 行输入为坐标x y以空格分隔,x,y为整数,-10<=x, y<=10

输出描述

输出可以构成的正方形数量。

用例

输入

3
1 3
2 4
3 1

输出 0 (3个点不足以构成正方形)
说明
输入

4
0 0
1 2
3 1
2 -1

输出 1
说明

题目解析

其实当我们知道正方形相邻两点的坐标,即某条边的坐标后,就可以求出其余两点的坐标。

如下图中,我们知道正方形的红色点坐标后,就画出绿色点坐标和橙色点坐标来形成两个正方形,这其中似乎隐藏着什么规律?

我们选取其中一个正方形来分析

我们在目标正方形外面包裹一个更大的正方形,此时可以发现大正方形和小正方形相交点切割出了相同的几个尺寸:d1和d2。

假设已知A点坐标(x1, y1),B点坐标(x2,y2),那么

  • d1 = x1 – x2
  • d2 = y1 – y2

其实很容易可以发现,d1含义是A,B两点横向距离,d2是A,B两点纵向距离。

基于A,B点坐标,以及d1,d2,我们可以算出C,D点坐标分别为:

  • C坐标 (x2 + d2, y2 – d1)
  • D坐标 (x1 + d2, y1 – d1)

继续转化一下可得:

  • C坐标 (x2 + y1 – y2, y2 – (x1 – x2))
  • D坐标 (x1 + y1 – y2, y1 – (x1 – x2))

这是求A,B右下方向C,D边得公式推导。

同理,可以根据A,B推导出其左上方向E,F边,图示如下:

基于A,B点坐标,以及d1,d2,我们可以算出E,F点坐标分别为: 

  • E坐标 (x1 – d2,y1 + d1)
  • F坐标 (x2 – d2,y1 + d1)

继续转化一下可得:

  • E坐标 (x1 – (y1 – y2),y1 + x1 – x2)
  • F坐标 (x2 – (y1 – y2),y1 + x1 – x2)

此时我们就得到了根据正方形任意相邻两点坐标,求另外两点坐标的公式了。

因此,接下来我们只需要遍历出两个点,然后通过公式得出另外可能的两个点,再在所有点中查找是否存在可能的两点,若存在,则正方形count++。

最后的正方形个数squareCount 需要除以 4,原因是,如果输入中真的存在如下图中的绿色,橙色点,则遍历过程中也会将绿色,橙色点遍历出来,然后求它们的可能正方形

也就是说上图中两个正方形,不仅会被两个红色点求出来两次次,还会被两个绿色点求出来一次,还会被两个橙色点求出来一次,还会被一绿一红求出来两次,被一橙一红求出来两次 ,总共是8次,而实际上只有2个正方形,因此最终结果要除以4。

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
let n;
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 1) {
    n = parseInt(lines[0]);
  }

  if (n && lines.length === n + 1) {
    lines.shift();

    console.log(getSquareCount(lines));

    lines.length = 0;
  }
});

/* 数学公式验证正方形 */
function getSquareCount(coordinates) {
  let squareCount = 0;

  const set = new Set(coordinates);

  for (let i = 0; i < coordinates.length; i++) {
    let [x1, y1] = coordinates[i].split(" ").map((ele) => parseInt(ele));

    for (let j = i + 1; j < coordinates.length; j++) {
      let [x2, y2] = coordinates[j].split(" ").map((ele) => parseInt(ele));

      let x3 = x1 - (y1 - y2);
      let y3 = y1 + (x1 - x2);
      let x4 = x2 - (y1 - y2);
      let y4 = y2 + (x1 - x2);
      if (set.has(x3 + " " + y3) && set.has(x4 + " " + y4)) squareCount++;

      let x5 = x1 + (y1 - y2);
      let y5 = y1 - (x1 - x2);
      let x6 = x2 + (y1 - y2);
      let y6 = y2 - (x1 - x2);
      if (set.has(x5 + " " + y5) && set.has(x6 + " " + y6)) squareCount++;
    }
  }

  return squareCount / 4;
}

Java算法源码

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int n = Integer.parseInt(sc.nextLine());

    String[] coordinates = new String[n];
    for (int i = 0; i < n; i++) {
      coordinates[i] = sc.nextLine();
    }

    System.out.println(getResult(n, coordinates));
  }

  public static int getResult(int n, String[] coordinates) {
    int squareCount = 0;

    HashSet<String> set = new HashSet<>(Arrays.asList(coordinates));

    for (int i = 0; i < n; i++) {
      Integer[] arr1 =
          Arrays.stream(coordinates[i].split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
      int x1 = arr1[0], y1 = arr1[1];

      for (int j = i + 1; j < n; j++) {
        Integer[] arr2 =
            Arrays.stream(coordinates[j].split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
        int x2 = arr2[0], y2 = arr2[1];

        int x3 = x1 - (y1 - y2), y3 = y1 + (x1 - x2);
        int x4 = x2 - (y1 - y2), y4 = y2 + (x1 - x2);

        if (set.contains(x3 + " " + y3) && set.contains(x4 + " " + y4)) squareCount++;

        int x5 = x1 + (y1 - y2), y5 = y1 - (x1 - x2);
        int x6 = x2 + (y1 - y2), y6 = y2 - (x1 - x2);
        if (set.contains(x5 + " " + y5) && set.contains(x6 + " " + y6)) squareCount++;
      }
    }

    return squareCount / 4;
  }
}

Python算法源码

# 输入获取
n = int(input())
coordinates = [input() for _ in range(n)]


# 算法入口
def getResult():
    squareCount = 0

    coordinatesSet = set(coordinates)

    for i in range(n):
        x1, y1 = map(int, coordinates[i].split())
        for j in range(i + 1, n):
            x2, y2 = map(int, coordinates[j].split())

            x3 = x1 - (y1 - y2)
            y3 = y1 + (x1 - x2)

            x4 = x2 - (y1 - y2)
            y4 = y2 + (x1 - x2)

            if f"{x3} {y3}" in coordinatesSet and f"{x4} {y4}" in coordinatesSet:
                squareCount += 1

            x5 = x1 + (y1 - y2)
            y5 = y1 - (x1 - x2)

            x6 = x2 + (y1 - y2)
            y6 = y2 - (x1 - x2)

            if f"{x5} {y5}" in coordinatesSet and f"{x6} {y6}" in coordinatesSet:
                squareCount += 1

    return squareCount // 4


# 算法调用
print(getResult())

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?