包含该点的三角形数量(0,0)(Number of Triangles Containing The Point (0,0))
首先,对Topcoder的信用,因为这个问题在他们的一个SRM中使用(但他们没有编辑...)
在这个问题中,我给了n个点(其中n在1到1000之间)。 对于每三个点,显然有一个连接它们的三角形。 问题是,这些三角形中有多少包含点(0,0)。
我试过在堆栈上查看这个线程:
但我无法理解使用什么数据结构/如何使用它们来解决这个问题。
这个问题的一个明显天真的解决方案是使用低效的O(n ^ 3)算法并搜索所有点。 但是,有人可以帮助我提高效率,并在O(n ^ 2)时间内完成此操作吗?
以下是Petr对这个问题的解决方案......它很短,但有一个我无法理解的大创意。
/** * Built using CHelper plug-in * Actual solution is at the top */ public class TrianglesContainOrigin { public long count(int[] x, int[] y) { int n = x.length; long res = (long) n * (n - 1) * (n - 2) / 6; for (int i = 0; i < n; ++i) { int x0 = x[i]; int y0 = y[i]; long cnt = 0; for (int j = 0; j < n; ++j) { int x1 = x[j]; int y1 = y[j]; if (x0 * y1 - y0 * x1 < 0) { ++cnt; } } res -= cnt * (cnt - 1) / 2; } return res; } }
First off, credits to Topcoder, as this problem was used in one of their SRMs (but they have no editorial for it..)
In this problem, I am given n points (where n is between 1 and 1000). For every three points, there is obviously a triangle that connects them. The question is, how many of these triangles contain the point (0,0).
I have tried looking at this thread on stack:
triangle points around a point
But I am unable to understand what data structures are used/how to use them to solve this problem.
An obvious naive solution to this problem is to use an inefficient O(n^3) algorithm and search all points. However, could someone please help me make this more efficient, and do this in O(n^2) time?
Below is Petr's solution to this problem... it is very short, but has a large idea I cannot understand.
/** * Built using CHelper plug-in * Actual solution is at the top */ public class TrianglesContainOrigin { public long count(int[] x, int[] y) { int n = x.length; long res = (long) n * (n - 1) * (n - 2) / 6; for (int i = 0; i < n; ++i) { int x0 = x[i]; int y0 = y[i]; long cnt = 0; for (int j = 0; j < n; ++j) { int x1 = x[j]; int y1 = y[j]; if (x0 * y1 - y0 * x1 < 0) { ++cnt; } } res -= cnt * (cnt - 1) / 2; } return res; } }
原文:https://stackoverflow.com/questions/27713046
最满意答案
因此,对于问题的这一部分,有一个绝对的答案:
为什么malloc失败,但不返回NULL。 这可能是可能的,或者我得到的错误信息的原因是其他吗?在Linux中,默认情况下,用于分配内存的内核接口几乎不会彻底失败。 相反,他们以这样的方式设置页表 :首次访问所请求的内存时,CPU将产生页面错误 ,此时内核会处理此错误 ,并查找将用于此目的的物理内存(虚拟)页面。 所以,在内存不足的情况下,你可以向内核请求内存,它会“成功”,并且当你第一次尝试触摸它返回的内存时, 这是分配实际上失败的时候,导致进程失效。 (或者也许还有其他一些不幸的受害者,这里有一些启发式的,我不是很熟悉,请参阅“ oom-killer ”。)
你的其他一些问题,答案对我来说不太清楚。
为什么在gdb下运行时以及没有调试器时,这种行为会有所不同?这可能(只是一个猜测)GDB有自己的malloc
,并且正在跟踪你的分配。 在一个相关的问题上,我经常发现我的代码中的堆错误在调试器中通常是不可重现的。 这是令人沮丧的,并让我挠了脑袋,但它基本上是我想到的一个人必须忍受的事情......我该如何解决?这是一个大锤解决方案(也就是说,它改变了所有进程的行为,而不仅仅是你自己的行为,而且你的程序改变全局状态通常不是一个好主意),但是你可以编写字符串
2
到/proc/sys/vm/overcommit_memory
。 查看我从Google搜索中获得的这个链接 。如果没有......我只是确保你没有超出预期的分配。
So, for this part of the question, there is a surefire answer:
Why would malloc fails yet not return a NULL. Could this be possible, or the reason for the error message i am getting is else?In Linux, by default the kernel interfaces for allocating memory almost never fail outright. Instead, they set up your page table in such a way that on the first access to the memory you asked for, the CPU will generate a page fault, at which point the kernel handles this and looks for physical memory that will be used for that (virtual) page. So, in an out-of-memory situation, you can ask the kernel for memory, it will "succeed", and the first time you try to touch that memory it returned back, this is when the allocation actually fails, killing your process. (Or perhaps some other unfortunate victim. There are some heuristics for that, which I'm not incredibly familiar with. See "oom-killer".)
Some of your other questions, the answers are less clear for me.
Why is this behaviour different when run under gdb and when without debugger?It could be (just a guess really) that GDB has its ownmalloc
, and is tracking your allocations somehow. On a somewhat related point, I've actually frequently found that heap bugs in my code often aren't reproducible under debuggers. This is frustrating and makes me scratch my head, but it's basically something I've pretty much figured one has to live with...How do i fix this?This is a bit of a sledgehammer solution (that is, it changes the behavior for all processes rather than just your own, and it's generally not a good idea to have your program alter global state like that), but you can write the string
2
to/proc/sys/vm/overcommit_memory
. See this link that I got from a Google search.Failing that... I'd just make sure you're not allocating more than you expect to.
相关问答
更多-
如果独立运行,gdb下Linux下的C代码运行方式不同?(C code on Linux under gdb runs differently if run standalone?)[2022-04-12]
因此,对于问题的这一部分,有一个绝对的答案: 为什么malloc失败,但不返回NULL。 这可能是可能的,或者我得到的错误信息的原因是其他吗? 在Linux中,默认情况下,用于分配内存的内核接口几乎不会彻底失败。 相反,他们以这样的方式设置页表 :首次访问所请求的内存时,CPU将产生页面错误 ,此时内核会处理此错误 ,并查找将用于此目的的物理内存(虚拟)页面。 所以,在内存不足的情况下,你可以向内核请求内存,它会“成功”,并且当你第一次尝试触摸它返回的内存时, 这是分配实际上失败的时候,导致进程失效。 (或 ... -
以C或C ++代码编程方式为Linux上的gdb设置断点(Set breakpoint in C or C++ code programmatically for gdb on Linux)[2022-03-09]
一种方式是发出中断信号: #include// Generate an interrupt std::raise(SIGINT); 在C: #include raise(SIGINT); 更新 : MSDN声明 Windows不真正支持SIGINT ,所以如果可移植性是一个问题,你可能更喜欢使用SIGABRT 。 One way is to signal an interrupt: #include // Generate an int ... -
GDB奇怪的行为 - Linux(GDB strange behavior - Linux)[2022-10-12]
我也在使用archlinux。 gdb -v GNU gdb (GDB) 7.8 qtcreator -version Qt Creator 3.2.0 based on Qt 5.3.1` 面对这种行为并解决了将gdb降级到版本7.7的问题 是的,你提到的gdb警告与手头的问题无关。 但没有找到为什么会发生这种情况。 I am too using archlinux. gdb -v GNU gdb (GDB) 7.8 qtcreator -version Qt Creator 3.2.0 based ... -
那是因为你在64位机器上,$ esp是32位寄存器。 你会想做x/s $ rsp That's because you're on a 64 bit machine, $esp is a 32 bit register. You'll want to do x/s $rsp
-
为什么gdb在这两种情况下表现不同? 因为您没有正确构建libdtest1.so以便GDB使用它。 特别是,你的libdtest1.so在其动态部分缺少DT_DEBUG条目,你可以这样确认: readelf -d libdtest1.so | grep DEBUG 你应该什么也看不见。 在正确构建的可运行的libdtest1.so (可以使用-pie标志构建)中,输出应如下所示: 0x00000015 (DEBUG) 0x0 运行时加载程序更新DT_DEBUG ...
-
给gdb一个让它暂停5秒的命令行选项的一种方法是告诉它在shell中运行“sleep 5”命令: --eval-command="shell sleep 5" One way to give gdb a command-line option that will make it pause for 5 seconds is to tell it to run the "sleep 5" command in a shell: --eval-command="shell sleep 5"
-
我不确定x64架构是否包含与x86相同的80位(长双)FP寄存器,但是当中间结果(即第一次乘法)保留在80-时,x86世界中的结果通常会出现。位寄存器而不是刷新回缓存/ RAM。 有效地计算的一部分是以更高的精度完成的,因此会产生不同的结果。 GCC有一个选项( -ffloat-store如果我的内存服务),它将导致中间结果被刷新回64位精度。 尝试启用它,看看你是否匹配GDB / Matlab结果。 I'm not sure if the x64 architecture contains the sam ...
-
有一个很棒的免费工具可以捕获指针,内存分配,解除分配等所有类型的运行时错误,这些错误在编译时无法捕获,所以编译器不会向你发出警告:valgrind http:// valgrind .org / 。 问题是,AFAIK它不能在Windows上运行。 但是,如果您的程序是纯ANSI C,那么您应该能够构建它并在Linux机器上使用valgrind运行它。 我不是百分之百确定它,但它应该在虚拟机中运行正常,所以如果你没有单独的Linux计算机,你可以尝试在Virtual Box或VmWare中安装例如Ubunt ...
-
GDB下的Linux线程性能非常快,但速度极慢(Linux thread performance very fast under GDB but extremely slow otherwise)[2022-08-11]
从未遇到过ARM上的pthread问题,我怀疑代码中存在竞争或初始化问题。 尝试将代码减少到重现问题的最小代码。 您应该在此处发布此代码,或者您认为相关的部分。 并且不要忘记,通常, 选择不会破碎 您使用的是LinuxThreads还是NPTL(“内核”线程?)如果您使用的是后者,您也可以尝试使用它。 Never had problem with pthreads on ARM, and I suspect there is a race or initialisation problem in your ... -
如何在Eclipse中启动gdb调试之前运行linux脚本(How to run a linux script before launching gdb debugging in Eclipse)[2024-04-09]
Eclipse Debug Configurations已经可以为您设置环境变量。 我会假设这还不够,或者你已经做到了。 首先要做的是创建一个新脚本wrapped-gdb.sh : #!/bin/sh # Export any variables we need. # Note that '.' (dot) is like an "include" statement. . /path/to/before-launch-commands.sh # Run GDB using the parameters ...