2366
题目介绍:
题目简介:
寻找有没有两个数加起来正好是10000。
方法:
提供了三种方法,详见解题思路:
- 双指针遍历数组
- 二分查找遍历数组
- Hash表查询
解题思路:
- 第一种思路:从两个数组的第一个元素开始遍历,如果相加大于10000,则访问第二组的下一个元素;若相加小于10000,则访问第一组的下一个元素。双指针
- 第二种思路:二分查找,遍历升序数组,在二分查找降序数组即可
- 第三种思路:HASH法,HASH最好的地方在于,不用排序,也不用开其他数组来存元素,此处判断为50000+a = 60000-b即可;在读入数据的时候就可以进行操作
完整代码:
#include "iostream"
#include "cstring"
#include "cstdio"
using namespace std;
#define MAXNUM 50005
#define HASHNUM 100005
#define SIGN 1; //1 2 3分别代表三种解题思路
int num1, num2;
int shengxu[MAXNUM], jiangxu[MAXNUM];
//第一种思路:从两个数组的第一个元素开始遍历,如果相加大于10000,则访问第二组的下一个元素;若相加小于10000,则访问第一组的下一个元素。双指针
int solve1(int a[MAXNUM], int b[MAXNUM]){
int i= 0, j=0;
while(i < num1 && j <num2){
if((a[i] + b[j])< 10000) {i++;
}
else if((a[i] + b[j])> 10000){j++;
}
else if((a[i] + b[j])== 10000) return 1;
}
return 0;
}
//第二种思路:二分查找,遍历升序数组,在二分查找降序数组即可
int BinarySearch(int x, int c[MAXNUM], int sum, int start, int end){
while (start <= end){
int mid = (start+end)/2;
if((x + c[mid])< sum) end = mid-1;
else if((x+c[mid]) >sum) start = mid+1;
else return 1;
}
return 0;
}
int solve2(int a[MAXNUM], int b[MAXNUM]){
for(int i = 0; i < num1;i++){
int ans = BinarySearch(a[i], b,10000, 0, num2-1);
if(ans == 1) return 1;
}
return 0;
}
//第三种思路:HASH法,HASH最好的地方在于,不用排序,也不用开其他数组来存元素,此处判断为50000+a = 60000-b即可;在读入数据的时候就可以进行操作
bool Hash[HASHNUM];
int main(){
cin >> num1;
for(int i = 0;i < num1;i++){
scanf("%d", &shengxu[i]);
}
cin >> num2;
for(int i = 0;i < num2;i++){
scanf("%d", &jiangxu[i]);
}
int ans;
#if SIGN ==1
ans = solve1(shengxu, jiangxu);
#elif SIGN == 2
ans = solve2(shengxu,jiangxu);
#endif
if(ans == 1) printf("YES\n");
else printf("NO\n");
/*-------------------------------------
* 以下用HASH法实现该题
-----------------------------------*/
#if SIGN == 3
cin >> num1;
int a, b;
while (num1--){
cin >> a;
Hash[50000+a] = true;
}
cin >> num2;
while(num2--){
cin >>b;
if(Hash[60000 - b]){
printf("YES\n");
return 0;
}
}
printf("NO\n");
#endif
return 0;
}