摘要:
前一篇文章讨论了二维坐标系下的判断,下面讨论三维的情况。 三维坐标下,对点的判断明显要复杂很多。如果google“Point in triangle”,第一个搜索结果就是这个网页,可惜的是,作者没有对结果进一步讨论,没有给出一个好的实现,而且其所有结论只在已知四点共面时才成立。 前面已经证明过,面积法和向量同向法是等价的。 ab × ac = ab × ap + ap × ac + pb × pc |ab × ac| = |ab × ap| + |ap × ac| + |pb × pc| 由于ab × a 阅读全文
摘要:
问题:判断点P是否在三角形ABC内 判断一个点是否在在三角形内,最常用的两种方法:面积法、向量同向法。算法虽然很简单,但要做到高效却不容易,要考虑到二维、三维的区别,还要考虑到坐标是用浮点数还是用整数来表示。 在二维平面上,问题相对简单,一般只需6次乘法计算。但在三维平面时问题要复杂很多,在网上看到的算法,一般都需要30次乘法计算(如果已知点P在平面ABC上,则需21次)。实际上,在三维坐标系下,可以做到增加1次比较,将乘法计算降到13次(如果点P在平面ABC上,则最多只要8次乘法计算)。 最常用的两种方法:面积法和向量同向法本质上是等价的。 向量同向法:若点P在三角形内,则三个向量:ab & 阅读全文
摘要:
看了几天asio文档,总算可以写点小程序了。有些细节还是没弄明白,同步IO好像还不能设超时?服务器端采用异步IO,客户端则采用同步IO。传送文件,不得不注意到 C/C++ 2G文件限制,好像没通用的解决方法。先定义下头文件,统一下asio和boost_asio。 #ifndef_FILE_INFO_H_#define_FILE_INFO_H_#ifUSE_ASIO_ALONE#include<asio.hpp>#else#include<boost/asio.hpp>namespaceasio{usingnamespaceboost::asio;usingboost:: 阅读全文
摘要:
要将一个数组的所有元素向左旋转k位,通常有三种算法:算法1(分组交换):若a长度大于b,将ab分成a0a1b,交换a0和b,得ba1a0,只需再交换a1 和a0。若a长度小于b,将ab分成ab0b1,交换a和b0,得b0ab1,只需再交换a 和b1。不断将数组划分和交换,直到不能再划分为止。分组过程与求最大公约数很相似。读写内存各 n到2*n次算法2 (三次反转)利用ba=(br)r(ar)r=(arbr)r,先分别反转a、b,最后再对所有元素进行一次反转。读写内存各约2*n次算法3 (使用循环链)假设 n、k的最大公约数为M,则所有序号为 (i + j*k) % n (0<= i &l 阅读全文
摘要:
全排列的hash函数,可以利用N位变进制,一般做法是用逆序数,但时间复杂度比较大。 设n位变进制数M,+i位逢i+1进一,显然M可表示的数的范围为[0, n!)共n!个 要生成n个数的排列,可以先从n个数挑一个,再从剩下的n-1个数挑一下,如此反复n次。 若最初的n个数是 0,1,2 ... n-1,第一次挑选的数是t,则可以将t放入到M的n-1位, 若第二次挑选的数是m,则 0 <= r <= n-1 且 r != t,当r等于n-1时, 不能将r放入到M的n-2位(可以放的最大数为n-2),但是注意到r值不可能为t, 该情况下将它的值改为t,得到的新r值肯定小等于n-2,因而可 阅读全文
摘要:
假设有某种很低级的芯片,不提供乘除法指令。问题1 计算从1加到N的和 (即 1 + 2 + 3 + ... + n)。问题2 求3的余数。对问题1,直接从1加到N,效率太差了,肯定不能这么干(小高斯都知道用乘法) 。既然不能用乘除法,那只好用加法来模拟了。 m * n,可以看做是 n个m相加,可以看做是 m,2*m, 4*m, 8*m, 16*m,... 中的几个相加。对问题2 设 n = 4 * a + b,则 n ≡ a + b (mod 3)unsignedsum(unsignedn){unsignedmin_v,max_v,ret=0;if(n&1){max_v=n;min_v 阅读全文
摘要:
SingleList*Reverse_SingleList(SingleList*head){SingleList*prev=NULL;while(head!=NULL){SingleList*next=head->next;head->next=prev;prev=head;head=next;}returnprev;} 阅读全文
摘要:
问题:寻找数组中的最小值和最大值。一道很简单的题目,一般有下面4种解法:1 遍历两次,每次分别找出最小值和最大值。2 只遍历一次,每次取出的元素先与已找到的最小值比较,再与已找到的最大值比较。3 每次取两个元素,将较小者与已找到的最小值比较,将较大者与已找到的最大值比较。4 分治:将数组划分成两半,分别找出两边的最小值、最大值,则最小值、最大值分别是两边最小值的较小者、两边最大值的较大者。这4种算法,哪种效率最高,哪种最低?后两种算法只要进行1.5*N次比较,因而网上有不少解答都将它们列为最佳答案。但是,算法4用到了递归,而递归法函数调用的开销是很大的,这就注定了该算法的效率肯定不高。那么,算 阅读全文
摘要:
思路很简单:如果数组头尾,不是一负一正,则可以直接判断。如果是一负一正: 直接二分搜索最小正数。再与前面的那个数比较绝对值。求递增数组中绝对值最小的数#include<cstdio>#include<cassert>//从递增数组(允许重复)中找出绝对值最小的数intbsearch(constintarr[],size_tlen){assert(len>0);constsize_tend=len-1;if(arr[0]>=0)returnarr[0];if(arr[end]<=0)returnarr[end];size_tlow=0,high=end; 阅读全文
摘要:
树状数组的二叉树解释 阅读全文