【问题标题】:Check whether two discs overlap in C检查两个圆盘是否在C中重叠
【发布时间】:2018-03-19 05:47:54
【问题描述】:

我必须输出非重叠光盘的数量。如果至少有一个点重叠(它们接触),则称两个圆盘重叠。我使用的重叠条件:
第一个输入是我应该从键盘读取的光盘数量。接下来的 n 行输入包含三个整数,即 x、y 坐标和该圆的半径。
问题是我的输出不正确,我尝试了各种条件来检查光盘是否重叠,但每次我得到不同的结果。比如输入下面的数据时,输出是5,什么时候应该是3。

10
0 0 5
1 7 1
6 0 3
-12 9 10
8 8 6
5 3 4
3 2 2
7 -10 7
3 15 2
-9 -7 7

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int **readDiscs(int n) //reading discs data into array
{
    int **discs = (int **) calloc(n, sizeof(int *));

    for (int i = 0; i < n; i++)
    {
        discs[i] = (int *) calloc(3, sizeof(int));
        for (int j = 0; j < 3; j++)
            scanf("%d", &discs[i][j]);
    }
    return (discs);
}

int checkOverlap(int **discs, int length)
{
    int *overlaps = (int *) calloc(length, sizeof(int));
    int k = 0, R1, R2, X1, X2, Y1, Y2;
    for (int i = 0; i < length; i++)
        for (int j = i + 1; j < length; j++)
        {
            R1 = discs[i][2];
            R2 = discs[j][2];
            X1 = discs[i][0];
            X2 = discs[j][0];
            Y1 = discs[i][1];
            Y2 = discs[j][1];
            if (sqrt(pow(X2 - X1, 2) + pow(Y2 - Y1, 2)) <= (R1 + R2))   //if the distance is less or equal to radius,
                overlaps[i] = 1;                                        //then they overlap or at least touch
        }
    for (int f = 0; f < length; f++)
        if (overlaps[f] == 0)
            k++;
    free(overlaps);
    return (k);
}

int main(int argc, char *argv[])
{
    int **discs;
    int n;
    scanf("%d", &n);
    discs = readDiscs(n);
    printf("%d\n", checkOverlap(discs, n));
    free(discs);
    return (0);
}

【问题讨论】:

  • 您有内存泄漏:您多次调用calloc 以获得discs,但您只调用了一次free
  • Basic debugging techniques: (1) 打印读取的数据以确保程序看到您认为它看到的内容; (2) 打印关键计算的结果——在这种情况下,打印中心之间的距离和半径之和并检查。这将帮助您确定出了什么问题。基本编码技术:检查文件打开和读取操作——它们有时会失败。
  • 你可以优化修正你的搜索,如果ij重叠,你可以为两个磁盘记录。因此,当重叠条件为真时,您应该有两个分配。事实上,我认为这是你的问题的原因。假设磁盘 1 和 4(共 4 个)重叠。您记录了 1 与 4 重叠,但您从未记录 4 与 1 重叠。
  • @JonathanLeffler,你的想法解决了问题。
  • 简洁地说,是的(您缺少对free()n 调用,它对应于main() 程序中discs 数组中的指针所指向的每个数组)。如果您还没有遇到Valgrind 并且您在支持它的平台上,那么您应该熟悉它。它会告诉您何时何地泄漏内存。

标签: c algorithm geometry


【解决方案1】:

您需要通过注意如果ij 重叠来修复您的搜索,您应该为这两个磁盘记录。因此,当重叠条件为真时,您应该有两个分配。

假设磁盘 1 和 4(共 4 个)重叠,但磁盘 2 和磁盘 3 都没有与任何磁盘重叠。您记录了 1 重叠(与 4),但您从未记录 4 与 1 重叠。

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2015-11-19
    • 2023-02-15
    相关资源
    最近更新 更多