题面描述:
有n个数和一个整数K,从这n个数中找出两个数,使这两个数的和为K,请问有多少组数满足条件(两个数可以重复,位置不同也算一组)。
输入:
第一行,一个整数T,表示有T组数据
第二行,两个整数,分别为N,K,n(2<=n<=100000),k(0<=k<2**31)。
第三行,N个数。
输出:
对于每组数据,输出这个问题的解。
Sample Input:
2
5 4
1 2 3 4 5
8 8
1 4 5 7 8 9 2 6
Simple Output:
3
5
解题思路:
枚举这n个数作为x,然后判断K-x是否在数组里面,这里的判断搜索使用二分搜索,如果是在数组里面,则计数ans+1,最后输出结果。
//代码一,C++写二分搜索
#include<stdio.h>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int a[100005],n,k;
int binarySearch(int l,int r,int x){
while(l<=r){
int mid=(l+r)/2;
if(a[mid]+x==k)return 1;
else{
if(a[mid]+x>k) r = mid - 1;
else l = mid + 1;
}
}
return 0;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int ans = 0;
scanf("%d %d",&n,&k);
for(int i = 1;i<=n;i++) scanf("%d",&a[i]);
a[0] = -INF;
sort(a,a+n+1);
for(int i = 1;i<=n;i++){
if(a[i]>k || a[i]==a[i-1]) continue;
if(binarySearch(1,n,a[i])) ans++;
}
printf("%d\n",ans);
}
}
//代码二,使用C、C++自带的bsearch()函数 作为二分查找函数
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int MAX = 1e5+1;
int a[MAX];
int binarySearch(const void* key,const void* e){
int* pNum1 = (int*)key;
int* pNum2 = (int*)e;
int num1 = *pNum1;
int num2 = *pNum2;
return num1 - num2;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,k;
scanf("%d %d",&n,&k);
for(int i = 0;i<n;i++) scanf("%d",&a[i]);
sort(a,a+n); //0~n,sort(a,a+n),1~n+1,sort(a,a+n+1)
int ans = 0;
for(int i = 0;i<n;i++){
int key = k-a[i];
int* item = (int*) bsearch(&key,a,n,sizeof(int),binarySearch);
if(item != NULL) ans++;
}
printf("%d\n",ans);
}
}
Tips:这里自带的sort()函数是从小到大进行排序,因此写binarySearch()函数时return num1 - num 2;
//代码三,使用Python写快速排序quickSort()函数
def binarySearch(key,a):
l = 0
r = n
while l<=r:
mid = (l+r)//2
if a[mid] == key:return 1
else:
if a[mid] > key:r = mid -1
else: l = mid + 1
return 0
def quickSort(arr):
if len(arr)<2:return arr
mid = arr[len(arr)//2]
left,right = [],[]
arr.remove(mid)
for e in arr:
if num >= mdi:right.append(num)
else:left.append(num)
return quickSort(left)+[mid]+quickSort(right)
for i in range(int(input())):
n,k = map(int,input().split())
a = quickSort(list(map(int,input().split()))) #调用quickSort()函数
ans = 0
for j in a:
key = k - j
if binarySearch(key,a):
ans += 1
print(ans)
//代码四,使用Python自带的sort()函数
def binarySearch(key,a):
l = 0
r = n
while l<=r:
mid = (l+r)//2
if a[mid] == key:return 1
else:
if a[mid] > key:r = mid -1
else: l = mid + 1
return 0
for i in range(int(input())):
n,k = map(int,input().split())
a = list(map(int,input().split()))
a.sort() //Python自带的sort()函数
ans = 0
for j in a:
key = k - j
if binarySearch(key,a):
ans += 1
print(ans)
模板 二分
C++版本:
int binarySearch(int nums[],int target){
int left = 0;
int right = nums.length-1;
while (left<=right){
//int mid = (left+right)/2;
int mid = left + ( right - left ) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid+1;
else right = mid-1;
}
return -1;
}
防止溢出:写法 ( left+right ) / 2 在 left 和 right 很大时容易溢出,可以改写成 left + ( right - left ) / 2 。
Python版本:
def binarySearch(arr,target):
left = 0
right = len(arr)-1
while left<=right:
mid = (left+right)//2
if arr[mid] == target:return mid
elif arr[mid] < target:left = mid+1
else:right = mid-1
return -1
ps:这种写法只能判断是否存在(速度最快)。而不能确保返回索引值在最左端还是最右端。例如:
arr = [7, 8, 3 ,1, 2, 7, 5,7]
返回的索引值是5,既不是最左端,也不是最右端的索引。