大概是整个实验里最简单的题了:(
题目描述
从前,有一对感情破裂的兄弟。为了拯救他们之间的感情,兄弟两人每个人都准备了一些对于他们来说可以拯救他们之间感情的数字,这些数字可以拯救他们的感情吗?(若在两个列表中的分别存在一个数,它们的和为10000,则我们认为这些数字可以拯救他们之间的感情)。你的程序应该决定,是否有可能从两个整数列表选择这样两个数字,来拯救他们的感情。
输入
每堆数(共2堆)的输入格式如下:每堆数的第一行,包含一个整数N ( 1 <= N <= 50,000 ),表示当前列表中的数字的个数;接下来N行,每一行包含一个整数A ( -32767<= A <=32767 )。输入数据保证:第一堆数按照升序排列,第二堆数按照降序排列。
输出
如果能找到符合要求的两个数,就输出"YES",否则输出"NO"。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
const int result = 10000;
int x,y;
cin >> x;
vector<int> nums1(x,0);
for(vector<int>::iterator it = nums1.begin(); it != nums1.end();it++){
cin >> *it;
}
cin >> y;
vector<int>nums2(y,0);
for(vector<int>::iterator it = nums2.begin(); it != nums2.end();it++){
cin >> *it;
}
int i = 0, j = 0;
while(i < x && j < y){
if(nums1[i]+nums2[j] == result){
cout << "YES";
break;
}
while(nums1[i] + nums2[j] > result) j++;
while(nums1[i] + nums2[j] < result) i++;
}
return 0;
}
另一解法:把问题转换成遍历其中一个数组nums2[i],假设值为x,则对于x只需在nums1中寻找是否存在10000-x的数即可。可用二分查找,二分查找时间复杂度为O(logn)【因为存在n个数,每次变成n/2,需要log2n次(以2为底的n的对数)。又因为要遍历一一遍数组nums2,所以为nlogn
#include <iostream>
#include <vector>
using namespace std;
const int result = 10000;
bool findAim(int x,vector<int>&nums1,int l,int r)
{
if(l > r)
return false;
int mid = (r+l)/2;
if(nums1[mid] == result-x)
return true;
if(result-x < nums1[mid])
return findAim(x,nums1,l,mid-1);
if(result-x > nums1[mid])
return findAim(x,nums1,mid+1,r);
}
int main()
{
int x,y;
cin >> x;
vector<int> nums1(x,0);
for(vector<int>::iterator it = nums1.begin(); it != nums1.end();it++){
cin >> *it;
}
cin >> y;
vector<int>nums2(y,0);
for(vector<int>::iterator it = nums2.begin(); it != nums2.end();it++){
cin >> *it;
}
bool j;
for(int i = 0; i < nums2.size(); i++){
j = findAim(nums2[i],nums1,0,x-1);
if(j){
cout << "YES";
break;
}
}
if(!j)
cout << "NO";
return 0;
}
c++bool类型会把非0转换为1(。