算法分析:第三种算法的复杂度也是O(nlogn)(其实是他规定的,没办法^_^),算法的具体思想有点类似,先将这个数组排序,然后利用二分查找来解决(不如第一种算法),枚举每个数组元素,然后查找是否存在一个有序数组中的数和他的和为x(不是本身),二分查找有序数组的时间复杂度为O(nlogn),乘以枚举的基数n,算法复杂度就是O(nlogn),加上排序的时间复杂度O(nlogn),总的分析下时间复杂度还是O(nlogn)(我好废话)。
代码实现:
#include<stdio.h>
#include<algorithm>
const int MAXN=5000;
int i,f,t,mid,n,x,a[MAXN];
int main()
{
scanf("%d",&n);
scanf("%d",&x);
for (i=0;i<n;i++)
scanf("%d",&a[i]);
std::sort(a,a+n);//再次偷懒用算法库了^_^
for (i=0;i<n;i++)
{
f=0;
t=n-1;
mid=(f+t)>>1;
while (f<t)
{
if (a[mid]+a[i]==x) break;
else if (a[mid]+a[i]<x) f=mid+1;
else t=mid-1;
mid=(f+t)>>1;
}
if (f>=t) continue;
if (mid!=i||(mid&&a[mid-1]+a[i]==x)||(mid!=n&&a[mid+1]+a[i]==x))
break;
}
if (i!=n) printf("%d %d\n",a[i],x-a[i]);
else printf("No Answer!\n");
return 0;
}
测试数据:同算法一
说明:不支持用这个算法,只是为了知识的完整性才列出,因为首先他的时间复杂度虽然也是O(nlogn),但是很容易想到不如算法一快,而且二分查找写代码容易发生错误,这点应该很多人知道(详细可以看看《算法珠玑》介绍的不错),总的来说,从个人感情上来讲,强烈支持第一种算法。
