Can you find it?——[二分查找]

Description

  Give you three sequences of numbers A, B, C, then we give you a number X. Now you need to calculate if you can find the three numbers Ai, Bj, Ck, which satisfy the formula Ai+Bj+Ck = X.

Input

  There are many cases. Every data case is described as followed: In the first line there are three integers L, N, M, in the second line there are L integers represent the sequence A, in the third line there are N integers represent the sequences B, in the forth line there are M integers represent the sequence C. In the fifth line there is an integer S represents there are S integers X to be calculated. 1<=L, N, M<=500, 1<=S<=1000. all the integers are 32-integers.

Output

  For each case, firstly you have to print the case number as the form "Case d:", then for the S queries, you calculate if the formula can be satisfied or not. If satisfied, you print "YES", otherwise print "NO".

Sample Input

3 3 3

1 2 3

1 2 3

1 2 3

3

1

4

10

Sample Output

Case 1:

NO

YES

NO

解题思路:

  首先我们考虑这个问题:给定两个序列A,B,和确定的数x,问是否存在i,j使满足A[i]+B[j]=x的?最快的方法是枚举A,然后在B中二分查找

x-A。现在回到这个问题,这道题给了三组序列A,B,C如何查找呢?我们不妨将A,C两数组合并成新数组LN,LN中每个元素都是Ai+Bj的和。然后枚举B,在LN中二分查找x-B。

*这里有个细节:由于x为32位整数,当A+B>INT32_MAX时,可以不用加入LN.

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <time.h>
 5 using namespace std;
 6 #define clock__ printf("%f\n",double(clock())/CLOCKS_PER_SEC);
 7 #define maxn 500
 8 #define INT_32_MAX ((1<<31)-1)
 9 typedef long long LL;
10 int A[maxn+3],B[maxn+3],C[maxn+3];
11 int L,M,N,S;
12 int LN[maxn*maxn+5];
13 int h;
14
15 bool search_LN(int a,int b,int x){
16     int len=b-a;
17     int mid=a+len/2;
18     if(len==1){
19         if(LN[a]==x) return true;
20         else return false;
21     }
22     if(LN[mid]==x) return true;
23     else if(LN[mid]>x) return search_LN(a, mid, x);
24     else return search_LN(mid, b, x);
25 }
26
27 int main() {
28
29     int T=0;
30     while(scanf("%d%d%d",&L,&M,&N)==3){
31         printf("Case %d:\n",++T);
32         for(int i=0;i<L;i++)
33             scanf("%d",&A[i]);
34         for(int i=0;i<M;i++)
35             scanf("%d",&B[i]);
36         for(int i=0;i<N;i++)
37             scanf("%d",&C[i]);
38         h=0;
39         for(int i=0;i<L;i++)
40             for(int j=0;j<N;j++){
41                 if(LL(A[i])+C[j]<=INT_32_MAX)
42                 LN[h++]=A[i]+C[j];
43             }
44         sort(LN, LN+h);
45         scanf("%d",&S);
46         for(int i=1;i<=S;i++){
47             int x;
48             scanf("%d",&x);
49             bool ok=0;
50             for(int j=0;!ok&&j<M;j++){
51                 if(search_LN(0,h, x-B[j]))
52                     ok=1;
53             }
54             if(ok)printf("YES\n");
55             else printf("NO\n");
56         }
57     }
58     //clock__
59     return 0;
60 }
时间: 2024-08-08 13:59:22

Can you find it?——[二分查找]的相关文章

River Hopscotch-[二分查找、贪心]

Description Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at th

714 - Copying Books——[贪心、二分查找]

Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of the most fa

二分查找原理和实现

前言 的确,我一开始的时候也认为二分查找挺简单的,但是在我对二分查找进行总结的时候,发现虽然思路很简单,但是代码要写的正确就不容易了. 区间 需要注意的是 注意计算的区间是左闭右开区间[)还是左闭右闭区间[],两者的代码是不太一样的. 左闭右闭区间 如果说你使用的是左闭右闭区间: int search3(int array[], int n, int target) { int left = 0; int right = n - 1; //比如说只有一个情况下 while (left <= ri

lintcode457. 经典二分查找问题

[一刷]报错了无数遍 一句话思路:对有序整数进行二分查找 问题: 数组长度有问题,不会表示:就用if (nums.length == 0)就行了.而且corner case要写到方法最前面. start,end没有初始化.应该初始化,因为是从第0位查找起的,题目中没说.考虑到有0,end=nums.length - 1 没有定义mid,也要先定义,但是一开始不赋值 返回的是start end的位置,不是数组的数值nums[start],nums[end] return-1顶格写,不用else 花

luogu P1120 小木棍 [数据加强版]

二次联通门 : luogu P1120 小木棍 [数据加强版] /* luogu P1120 小木棍 [数据加强版] 暴搜 + 剪枝 枚举可能的长度 挨个检查答案 二分显然正确性不能保障 搜索时从最大的开始找 放上当前木棍后的长度比枚举的长度要大, 则退出 若当前的长度与当前扫到的木棍长度相同, 或是还需要的长度与枚举的长度相同,则退出 若当前的木棍不符合要求, 则后面与它长度相同的木棍都不行 */ #include <algorithm> #include <iostream>

二分查找

递归版(在区间[x, y)中找v的位置) 1 //递归版二分查找 2 int bsearch(int * A, int x, int y, int v) 3 { 4 5 if(v<a[x] || v>a[y-1]) return -1; 6 int m = x + (y-x)/2; //此处能不能用int m = (x+y)/2,需要仔细考虑(暂时想不到原因) 7 if(A[m]==v) return m; 8 else if(A[m]>v) return bsearch(A, x, m

二分查找总结

最近刷leetcode和lintcode,做到二分查找的部分,发现其实这种类型的题目很有规律,题目大致的分为以下几类: 1.最基础的二分查找题目,在一个有序的数组当中查找某个数,如果找到,则返回这个数在数组中的下标,如果没有找到就返回-1或者是它将会被按顺序插入的位置.这种题目继续进阶一下就是在有序数组中查找元素的上下限.继续做可以求两个区间的交集. 2.旋转数组问题,就是将一个有序数组进行旋转,然后在数组中查找某个值,其中分为数组中有重复元素和没有重复元素两种情况. 3.在杨氏矩阵中利用二分查

二分查找JAVA实现

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 一.概念 二分查

rwkj 1430 二分查找

#include<iostream>using namespace std;int n,k,a[10000]; int binsearch(int low,int high){ int i,len,s;while(low<high) { len=(high+low)/2; for(s=0,i=0;i<n;i++) s+=a[i]/len; if(s>k) low=len+1; else if(s<k) high=len-1; else return len; }}int