E-构成正方形的数量(100p)

刷题笔记合集🔗

构成正方形的数量

问题描述

给定 个互不相同的二维整数坐标点,求这 个坐标点可以构成的正方形数量。需要注意的是,两个向量的内积为零时,这两个向量垂直。

输入格式

第一行输入一个正整数 ,表示坐标点的数量。

接下来的 行,每行包含两个整数 ,以空格分隔,表示一个坐标点

输出格式

输出一个整数,表示可以构成的正方形数量。

样例输入1

3
1 3
2 4
3 1

样例输出1

0

样例输入2

4
0 0
1 2
3 1
2 -1

样例输出2

1

样例解释

样例 解释说明
样例1 3个点不足以构成正方形,因此输出0。
样例2 4个点可以构成1个正方形,因此输出1。

数据范围

题解

这道题目要求我们计算给定的 个点中可以构成的正方形数量。解决这个问题的关键在于理解正方形的性质和如何利用坐标系中的点来判断正方形。

首先,我们需要明白,一个正方形可以由任意两个点确定。当我们知道正方形的一条边(即两个点的坐标)时,我们就可以计算出其他两个点的坐标。

解题思路如下:

  1. 枚举任意两个点作为正方形的一条边。
  2. 根据这两个点,计算出可能的其他两个点的坐标。
  3. 检查计算出的点是否在给定的点集中。
  4. 如果所有四个点都在点集中,则找到了一个正方形。

参考代码

  • Python
def count_squares(points):
    # 将点集转换为集合,方便快速查找
    point_set = set(points)
    n = len(points)
    count = 0

    # 枚举所有可能的点对
    for i in range(n):
        for j in range(i + 1, n):
            x1, y1 = map(int, points[i].split())
            x2, y2 = map(int, points[j].split())
            
            # 计算第一组可能的正方形点
            x3 = x1 - (y1 - y2)
            y3 = y1 + (x1 - x2)
            x4 = x2 - (y1 - y2)
            y4 = y2 + (x1 - x2)
            
            # 检查这两个点是否在点集中
            if f"{x3} {y3}" in point_set and f"{x4} {y4}" in point_set:
                count += 1

            # 计算第二组可能的正方形点
            x5 = x1 + (y1 - y2)
            y5 = y1 - (x1 - x2)
            x6 = x2 + (y1 - y2)
            y6 = y2 - (x1 - x2)
            
            # 检查这两个点是否在点集中
            if f"{x5} {y5}" in point_set and f"{x6} {y6}" in point_set:
                count += 1

    # 由于每个正方形被计算了4次,所以需要除以4
    return count // 4

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

# 计算并输出结果
result = count_squares(points)
print(result)
  • C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义点的最大数量
#define MAX_POINTS 1000
// 定义单个点的字符串长度 (例如 "123 456")
#define MAX_POINT_LEN 20

// 字符串集合结构体
typedef struct {
    char points[MAX_POINTS][MAX_POINT_LEN]; // 存储点的字符串
    int size; // 集合中的点数量
} PointSet;

// 初始化点集合
void initPointSet(PointSet *set) {
    set->size = 0;
}

// 向点集合中添加一个点
void addPoint(PointSet *set, const char *point) {
    strcpy(set->points[set->size], point);
    set->size++;
}

// 检查集合中是否包含指定的点
int containsPoint(PointSet *set, const char *point) {
    for (int i = 0; i < set->size; i++) {
        if (strcmp(set->points[i], point) == 0) {
            return 1; // 找到匹配的点
        }
    }
    return 0; // 未找到匹配的点
}

// 计算可能的正方形数量
int countSquares(char points[MAX_POINTS][MAX_POINT_LEN], int n) {
    PointSet pointSet;
    initPointSet(&pointSet);

    // 将所有点添加到集合中
    for (int i = 0; i < n; i++) {
        addPoint(&pointSet, points[i]);
    }

    int count = 0;

    // 遍历所有可能的点对 (i, j)
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int x1, y1, x2, y2;
            sscanf(points[i], "%d %d", &x1, &y1); // 从第一个点获取坐标
            sscanf(points[j], "%d %d", &x2, &y2); // 从第二个点获取坐标

            // 计算第一组可能的正方形点
            int x3 = x1 - (y1 - y2);
            int y3 = y1 + (x1 - x2);
            int x4 = x2 - (y1 - y2);
            int y4 = y2 + (x1 - x2);

            // 构造两个点的字符串表示
            char p3[MAX_POINT_LEN], p4[MAX_POINT_LEN];
            snprintf(p3, MAX_POINT_LEN, "%d %d", x3, y3);
            snprintf(p4, MAX_POINT_LEN, "%d %d", x4, y4);

            // 检查这两个点是否存在于集合中
            if (containsPoint(&pointSet, p3) && containsPoint(&pointSet, p4)) {
                count++;
            }

            // 计算第二组可能的正方形点
            int x5 = x1 + (y1 - y2);
            int y5 = y1 - (x1 - x2);
            int x6 = x2 + (y1 - y2);
            int y6 = y2 - (x1 - x2);

            // 构造第二组两个点的字符串表示
            char p5[MAX_POINT_LEN], p6[MAX_POINT_LEN];
            snprintf(p5, MAX_POINT_LEN, "%d %d", x5, y5);
            snprintf(p6, MAX_POINT_LEN, "%d %d", x6, y6);

            // 检查这两个点是否存在于集合中
            if (containsPoint(&pointSet, p5) && containsPoint(&pointSet, p6)

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论
有需要的宝子可以订阅专栏哦~
点赞 回复 分享
发布于 2024-10-31 11:56 浙江

相关推荐

2025-12-12 19:01
南京航空航天大学 C++
秋招没咋投,准备&nbsp;wxg&nbsp;转正之后摆烂了。结果不堪字节&nbsp;HR&nbsp;的骚扰还是面了一下字节。之前想去字节的时候怎么面都挂。现在想着随便面一下结果三面技术面都意外顺利还有加面。十月中旬字节发了意向,wxg&nbsp;转正结果无响应。十月底字节拉了保温群,wxg&nbsp;口头通过,系统显示考核中。十一月初和字节&nbsp;ld&nbsp;交流之后得知&nbsp;base&nbsp;居然能选海外,甚至能小&nbsp;wlb&nbsp;一下,wxg&nbsp;无响应无人联系。十一月中旬把字节&nbsp;base&nbsp;转到了海外,wxg&nbsp;流程灰了,一问超时忘处理了,过两天又变考核中了。十一月下旬字节换了海外&nbsp;HR&nbsp;对接,问了期望薪资,wxg&nbsp;考核终于显示通过,无&nbsp;HR&nbsp;保温,无其他保温。十一月底给字节报了个天价,想吓吓他们,同时告诉微信字节要开了,微信无响应。同样十一月底字节&nbsp;HR&nbsp;告诉我确实给不到那么高,但是能拿期权补上,问能不能接受。微信无响应。同样十一月底字节&nbsp;HR&nbsp;告知了具体方案,符合预期。&nbsp;微信无响应。十二月上旬催&nbsp;wxg&nbsp;不开我就盲拒了,wxg&nbsp;HR&nbsp;火急火燎的打电话问情况,问期望。我给了一个不算夸张的总包数字,因为今年市场在涨,过了三天还不联系我,我再催,约时间下午打电话,非得在我给出的数字上压下去几万,微信又不差这点,为什么不能满足我,让我没有拒绝的理由呢?一番纠结抗争,求稳还是追求挑战,最终选择接受迎接新的挑战,因为堂吉诃德永远不会停下脚步!回想起来,在&nbsp;wxg&nbsp;谈薪的阶段,我认为并没有给予我一定的重视,即使&nbsp;HR&nbsp;表示我在实习期间的表现和之前的面评都很靠前。也没有感觉到想要争取我,虽然我表示拒了&nbsp;offer&nbsp;之后要给我加面委定&nbsp;t6&nbsp;再涨,但我三个月没面试让我面面委那就是白给,还是算了。有缘再见了我亲爱的&nbsp;wxg,再见了曾经的梦中情厂,再见亲爱的&nbsp;mt,再见亲爱的朋友们。也再见,北京的一切。我想润了。秋招结束,卸载牛客,下一个三年,下一个五年,下一个十年后再来看看。
面试中的大熊猫爱吃薯...:我嫉妒得狗眼通红
点赞 评论 收藏
分享
评论
2
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务