51Nod ~ 1267 ~ 4个数和为0(二分or尺取)
思路: N的范围为1000,所以四重for循环枚举显然不行。所以我们可以先将两个不同数字相加的结果算出来,然后问题就变为在这个数组中找到两个数字相加等于0的问题。 如果在枚举一个数字,在这个集合中寻找它的负数,可是我们这样复杂度依旧为n^2*n^2=n^4会超时。我们有两种做法(先对数组排序 ): <1> 二分查找,枚举一个数二分查找他的负数,复杂度为 ,这样就能过了。可是你在仔细想想这四个数字不能重叠,可能会出现A+B+B+C=0的情况,所以这样写是有BUG的,所以我们要对每两个数字的和做标记表示他是由哪两个数字相加得出来得(用个结构体就可以了)。再想一下二分可能得情况,对于当前枚举的数字sum[i],查找数组为sum查找值key=-sum[i],①key<sum[m],使L=m+1向右缩区间 ②key>sum[m],使R=m-1向右缩区间 ③key==sum[m],这种时候我们要判断是不是sum[i]=A+B,sum[m]=B+X,sum[i]+sum[m]=A+B+B+X=0的情况,如果不是就找到了答案直接跳出到最外层输出答案就行了,否则的话跳出二分,去枚举下一个数字就可以(为什么?解释在下面关键点中)。 <2> 我们也可以采取尺取法,复杂度为 。然后定义两个指针i从前往后扫,j从后往前扫,①sum[i]+sum[j]<0,这时候让i++②sum[i]+sum[j]>0,让j